如何在另一个线程的 tkinter 中打开 tk 窗口(tkinter 不是线程安全的)



我想使用Tkinter GUI编写一个程序,它在线程中执行特定任务。当任务执行过程中发生错误时,程序应该弹出一个错误窗口,例如使用tkMessageBox。当然,当程序应该从新线程弹出消息框时会崩溃,因为Tkinter不是线程安全的,但我希望这个问题有一个解决方案。

以下是一个不工作代码(编辑(的简单示例:

from tkinter import *
import tkMessageBox
from threading import *
import time

class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.button = Button(frame, text = "Task", command = self.thread_task)
self.button.pack(side=LEFT)
def thread_task(self):
thread = Thread(target = self.task)
thread.start()
def task(self):
#perform task...          
time.sleep(1) #Just as a filler in the code
#command to open an error popup, e.g. tkMessageBox.showerror("Error", "Problem occured")
root = Tk()
app = App(root)
root.mainloop()

您可以在线程内部使用try。

以下是一个基于您的代码的示例(经过编辑以使用Python 2(:

from Tkinter import *
import tkMessageBox
from threading import *

class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.button = Button(frame, text="Task", command=self.thread_task)
self.button.pack(side=LEFT)
def thread_task(self):
thread = Thread(target=self.task)
thread.start()

def task(self):
try:
time.sleep(1)
self.button["text"] = "Started"
self.button["state"] = "disabled"
raise ValueError  # or anything else
except:
tkMessageBox.showerror("Error", "Problem occured")
self.button["text"] = "Task"
self.button["state"] = "normal"
if __name__ == "__main__":
root = Tk()
app = App(root)
root.mainloop()

最新更新