繁体   English   中英

使用线程更新 Tkinter GUI

[英]Updating Tkinter GUI w/ threading

我正在开发一个遵循基本结构的项目:一个音序器类实例化一个 GUI 类,该类提供更新/修改 GUI 内容的功能(更改背景图像、更新文本字段等)。 在排序器类中,我想启动一些执行某些操作(包括一些run_test time.sleep()命令,并更新 GUI 以显示测试正在运行的方法 run_test。显然,GUI 主循环在发生这种情况时会冻结,并且GUI 不会更新。

这里的正确解决方案是什么? 如何在另一个线程中启动 run_test 以便 GUI 可以更新?

class TestSequencer():

    def __init__(self):
        self._gui = TestGUI(sequencer=self)
        self._gui.run_gui()

    def start_sequencer(self):
        self._gui.update_background_image()
        self.run_test()

    def run_test(self):
        time.sleep(5)

结果是代码休眠 5 秒,之后 GUI 更新背景图像。 我希望它立即发生,并且可能随着 run_test 期间发生的各种事情而动态发生(例如,根据 run_test 的通过/失败,在 GUI 上显示不同的内容)。

我该如何实现?!

我这里有一些代码可以帮助你。 我已经遇到了你的问题,我通过线程另一个将运行我的代码的类来解决这个问题。 所以不幸的是我不能显示整个代码,但我试图给你一些可以帮助的东西。

DELAY = 100  # millisecs between status label updates

# global flag and a Lock to control concurrent access to it
run_flag_lock = threading.Lock()
running = False

class RunningClass(threading.Thread):
    def __init__(self):
        self.run()

    def run(self):
        global running
        # random work
        YOUR CODE
        with run_flag_lock:
            running = False

class GUI(Frame, object):
    def __init__(self, master)
        super(GUI, self).__init__(master)
        global running
        self.button = Button(self, text="EXECUTE", command=lambda: self.execute(), bg="green", fg='white')
        self.button.grid(row=0, column=0, sticky=E + W)
        with run_flag_lock:
            running = False
        self.after(DELAY, self.update_status, None)  # start status widget updating

    def update_status(self, run_state):
        global running
        """ Update status label text and state of buttons to match running flag. """
        # no need to declare run_flag_lock global since it's not being assigned a value
        with run_flag_lock:
            if running != run_state:  # status change?
                if running:
                    run_state = True
                else:
                    run_state = False
            else:
                try:
                    x = self.temp
                except:
                    pass
        # run again after a delay to repeat status check
        self.after(DELAY, self.update_status, run_state)


    def execute(self):
        global running
        flag_error = False
        with run_flag_lock:
            if not running:
                self.temp = RunningClass()
                self.temp.start()
                running = True

if __name__ == '__main__':
    ROOT = Tk()
    ROOT.title("TEXT")
    LOGIN = GUI(ROOT)
    LOGIN.grid(sticky=E)
    ROOT.mainloop()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM