运行后台线程时了解Tkinter窗口响应

时间:2016-03-09 17:04:28

标签: python multithreading user-interface tkinter

我正在使用Tkinter创建一个从计算线程不断更新的GUI。为了保持GUI响应,我在这个线程的每个循环中创建一个事件,告诉主线程(在其中创建了Tkinter窗口)用计算数据更新GUI。线程的结构如下所示:

class background_thread(threading.Thread):
    def __init__(self, parent, stopper):
        threading.Thread.__init__(self)

        self.parent  = parent
        self.stopper = stopper

        ### Init. variables ###

    def run(self):
        while(not self.stopper.is_set()):

            ### Compute data ###

            root.event_generate("<<update_gui>>", when = "now")

这很好用,但是当线程运行时我无法理解我的Tkinter窗口的行为。首先,即使我的mainloop()仍然响应(我每秒大约40帧),窗口本身根本没有响应。通过这个,我的意思是它不可能拖动它或关闭它。这是什么原因,有什么办法可以阻止它吗?

由此产生的一个问题是我必须在关闭窗口之前停止线程。为此,我使用一个切换其执行的按钮:

def callback_toggle_thread(self, event):    
    if(not self.background_thread.isAlive()):
        self.background_thread.start()
    else:
        self.stopper.set()

但如果我尝试重新定义窗口关闭按钮protocole:

root.protocol("WM_DELETE_WINDOW", on_closing)

def on_closing():
    if(self.background_thread.isAlive()):
        self.stopper.set()                  # Asks the thread to stop
        self.background_thread.join()       # Waits for the thread to stop

    root.destroy()                          # Closes the window

程序刚冻结。我做错了吗?

1 个答案:

答案 0 :(得分:0)

正如我在a comment中建议的那样,如果在后台线程中生成事件后调用root.update(),它将强制应用程序自行更新。这个fixed the original issue虽然我无法完成特定的执行流程,因为示例代码不足以进行测试。