Stop Thread без закрытия окна GUI - PullRequest
1 голос
/ 10 апреля 2020

Я учу python самостоятельно, и мой уровень, вероятно, является плохим оправданием для "сценария, детка" ie, насколько я понимаю, и в основном заканчиваю тем, что заимствую и смешиваю разные сценарии, пока не получу то, что хочу. Однако я впервые пытаюсь создать GUI для одного из моих скриптов. Я использую PySimple GUI, и я смог удивительно хорошо это понять. Все, кроме одного, работает так, как я хочу.

Проблема в том, что я хочу остановить работающий поток демона, не выходя из GUI. Если я заставлю работать кнопку остановки, GUI закрывается, и если GUI не закрывается, это не останавливает поток. Проблема находится между строк "64 -68". Я попробовал несколько вещей и просто поместил заполнитель в строку '65', чтобы помнить, что я пытался сохранить работу GUI ("Основной поток" в моей голове). Сценарий будет работать в этом состоянии, но кнопка «Стоп» не работает.

Примечание. Я добавил много комментариев в свои сценарии, чтобы запомнить, что такое каждая часть, что она делает и что мне нужно убирать Я не знаю, если это хорошая практика, если я планирую поделиться сценарием. Также, если это имеет значение, я использую Visual Studio Code.

#!/usr/local/bin/python3

import PySimpleGUI as sg
import pyautogui
import queue
import threading
import time
import sys
from datetime import datetime
from idlelib import window

pyautogui.FAILSAFE = False
numMin = None

# ------------------ Thread ---------------------

def move_cursor(gui_queue):
    if ((len(sys.argv)<2) or sys.argv[1].isalpha() or int(sys.argv[1])<1):
        numMin = 3
    else:
        numMin = int(sys.argv[1])
    while(True):
        x=0
        while(x<numMin):
            time.sleep(5)                   # Set short for debugging (will set to '60' later)
            x+=1
        for i in range(0,50):
            pyautogui.moveTo(0,i*4)
        pyautogui.moveTo(1,1)
        for i in range(0,3):
            pyautogui.press("shift")
        print("Movement made at {}".format(datetime.now().time()))  

# --------------------- GUI ---------------------

def the_gui():
    sg.theme('LightGrey1')                  # Add a touch of color
    gui_queue = queue.Queue()               # Used to communicate between GUI and thread


    layout = [  [sg.Text('Execution Log')],
             [sg.Output(size=(30, 6))],
             [sg.Button('Start'), sg.Button('Stop'), sg.Button('Click Me'), sg.Button('Close')]  ]
    window = sg.Window('Stay Available', layout)

# -------------- EVENT LOOP ---------------------
    # Event Loop to process "events"

    while True:
        event, values = window.read(timeout=100)
        if event in (None,'Close'):
          break
        elif event.startswith('Start'):     # Start button event
            try:
                print('Starting "Stay Available" app')
                threading.Thread(target=move_cursor,
                                 args=(gui_queue,), daemon=True).start()
            except queue.Empty:
                print('App did not run')
        elif event.startswith('Stop'):      # Stop button event
            try:
                print('Stopping "Stay Available" app')
                threading.main_thread       # To remind me I want to go back to the original state
            except queue.Empty:
                print('App did not stop')
        elif event == 'Click Me':           # To see if GUI is responding (will be removed later)
            print('Your GUI is alive and well')

    window.close(); del window

if __name__ == '__main__':
    gui_queue = queue.Queue()               # Not sure if it goes here or where it is above
    the_gui()
    print('Exiting Program')
...