【问题标题】:Trying to Exit a While True Loop using PySimpleGUI尝试使用 PySimpleGUI 退出 While True 循环
【发布时间】:2021-11-08 21:03:06
【问题描述】:

这是我的代码:

Main.py:

import PySimpleGUI as sg
import Config
import threading


def main():
    layout = [  [sg.Text('Real Time Raspberry Pi Sniffer')],
            [sg.Button('Run While Loop'), sg.Button('Exit')],     # a couple of buttons
            [sg.Output(size=(60,15))] ]         # an output area where all print output will go
            #[sg.Input(key='_IN_')] ]             # input field where you'll type command

    window = sg.Window('Realtime Shell Command Output', layout)

    while True:            # Event Loop
        event, values = window.Read()
        if event == 'Run While Loop':             
            t1 = threading.Thread(target = Config.whileLoop())
            t1.start()
        elif event == 'Exit' or event == WIN_CLOSED:
            print('CLICKED EXIT') 
            window.Close()

if __name__ == '__main__':
    main()

Config.py

from PySimpleGUI.PySimpleGUI import WIN_CLOSED
def whileLoop():
    state = True
    while (state == True):          
        print("It works!")  

我正在尝试创建在用户单击按钮时运行 while 循环的 GUI 窗口(在这种情况下,当他们单击“Run While Loop”时)。但是,我遇到了一个问题,因为我的代码卡在了 Config.py 中的嵌套 while 循环中。我希望代码能够退出 while 循环并在单击“退出”按钮时由程序停止。我研究了线程,不知道还能做什么。有什么帮助,谢谢!

【问题讨论】:

  • 在 Python 中,由于全局解释器锁 (GIL),线程不会真正并发执行。它更多的是合作多任务的情况。 config.py 中的循环太“紧”,绝不允许发生线程切换。在循环内短时间添加time.sleep(),让主线程也有机会运行。
  • 如果你不改变state的值,config.py while循环不会退出。
  • @martineau 当我添加它时,GUI 只是说“没有响应”。你知道我应该怎么做才能连接这两个程序,这样当我点击开始时它会运行while循环,当我点击退出时它会停止程序?
  • 您是否将参数传递给time.sleep(),例如time.sleep(.1)?抱歉,我对PySimpleGUI 本身了解不多,只知道tkinter
  • 当您点击退出时,您必须更改配置模块中的state 变量,这样循环才会退出。我会把它放在 WAG 答案中。

标签: python while-loop pysimplegui


【解决方案1】:

我导入Config.py中定义的类Func,然后调用实例Func()的方法while_loop。为 while 循环是否继续运行设置一个标志 True 或 False。

示例代码

# Config.py

from time import sleep
from PySimpleGUI import WIN_CLOSED


class Func():

    def __init__(self):
        self.state = False
        self.count = 0

    def while_loop(self, window):
        while self.state:
            sleep(0.5)                                      # Simulate job done here
            self.count += 1
            window.write_event_value("Done", self.count)    # update GUI by event
# main.py

from time import sleep
from threading import Thread
import PySimpleGUI as sg
import Config


def main():

    layout = [
        [sg.Text('Real Time Raspberry Pi Sniffer')],
        [sg.Button('Start'), sg.Button('Stop'), sg.Button('Exit')],
        [sg.StatusBar('', size=60, key='Status')],
    ]
    window = sg.Window('Realtime Shell Command Output', layout, enable_close_attempted_event=True)
    status = window['Status']
    func = Config.Func()
    thread = None
    while True:

        event, values = window.read()

        if event in (sg.WINDOW_CLOSE_ATTEMPTED_EVENT, 'Exit'):
            func.state = False
            sleep(0.5)  # Wait thread to stop
            break
        elif event == 'Start' and thread is None:
            func.state = True
            func.count = 0
            thread = Thread(target=func.while_loop, args=(window,), daemon=True)
            thread.start()
        elif event == 'Stop':
            func.state = False
            thread = None
        elif event == 'Done':
            count = values[event]
            status.update(f"Job done at #{count:0>3}")

    window.Close()

if __name__ == '__main__':
    main()

【讨论】:

    【解决方案2】:

    这是一个猜测,因为我以前没有做过你正在尝试的事情。

    也许如果你把你的 config.py 改成这样:

    state=True
    def whileLoop():
       while (state == True):          
           print("It works!") 
    

    (使 state 成为模块全局标志)

    并修改您的事件循环,如:

    while True:            # Event Loop
        event, values = window.Read()
        if event == 'Run While Loop':             
            t1 = threading.Thread(target = Config.whileLoop())
            t1.start()
        elif event == 'Exit' or event == WIN_CLOSED:
            print('CLICKED EXIT') 
            Config.state = False # set the exit flag
            t1.join() # I'm not sure about this, could try without
            window.Close()
    

    再说一次,我用 Python 很长时间了,但从来没有这样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-14
      • 2019-05-08
      相关资源
      最近更新 更多