我正在使用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
程序刚冻结。我做错了吗?
答案 0 :(得分:0)
正如我在a comment中建议的那样,如果在后台线程中生成事件后调用root.update()
,它将强制应用程序自行更新。这个fixed the original issue虽然我无法完成特定的执行流程,因为示例代码不足以进行测试。