我有一个tkinter应用程序(作为主线程运行),在它里面我打开了一个新的顶层窗口——它是一个日志窗口,打印测试结果(测试是用selenium webdriver执行的)。此对话框也是所有测试的调用者。在
所以我想显示对话框(作为顶层,还有一个窗口用于整个应用程序),运行一个测试,直到测试完成并打印结果,然后对另一个测试单元执行相同的操作。但我不想让窗户在测试期间冻结。在
我尝试过使用线程,但显然它可以像那样工作。在这种情况下,直到测试完成,对话框才会启动。在
这是对话框窗口的代码。在
class TestDialog(tkinter.Toplevel):
def __init__(self, parent, tester, url):
super().__init__(parent)
self.parent = parent
self.webtester = tester;
self.__initComponents()
self.run(url)
self.wait_window(self)
def __initComponents(self):
self.transient(self.parent)
frame = tkinter.Frame(self)
self._tarea = tkinter.Text(frame, state='disabled',wrap='none', width=55, height=25)
vsb = tkinter.Scrollbar(frame, orient=tkinter.VERTICAL, command=self._tarea.yview)
self._tarea.configure(yscrollcommand=vsb.set)
self._tarea.grid(row=1, column=0, columnspan=4, sticky="NSEW", padx=3, pady=3)
vsb.grid(row=1, column=4, sticky='NS',pady=3)
frame.grid(row=0, column=0, sticky=tkinter.NSEW)
frame.columnconfigure(0, weight=2)
frame.rowconfigure(1, weight=1)
window = self.winfo_toplevel()
window.columnconfigure(0, weight=1)
window.rowconfigure(0, weight=1)
self.bind("<Escape>", self.close)
self.protocol("WM_DELETE_WINDOW", self.close)
self.grab_set()
def appendLine(self, msg):
self._tarea['state'] = 'normal'
self._tarea.insert("end", msg+'\n')
self._tarea['state'] = 'disabled'
def run(self, url):
self.appendLine("Runneing test #1...")
try:
thr = threading.Thread(target=self.webtester.urlopen, args=(url,))
thr.start()
except:
pass
thr.join()
self.webtester.urlopen(url)
self.appendLine("Running test #2")
try:
thr = threading.Thread(target=self.webtester.test2)
thr.start()
except:
pass
def close(self, event=None):
self.parent.setBackgroundScheme(DataTreeView.S_DEFAULT)
self.parent.focus_set()
self.destroy()
此对话框只需通过以下操作从父窗口打开:
^{pr2}$谢谢你的建议。在
为了防止GUI冻结,您需要
self.run()
快速结束。 它需要生成一个线程,启动线程,然后结束:现在这个线程运行的函数可以长时间运行:
^{pr2}$但是因为Tkinter期望所有GUI调用都来自一个线程,所以这个派生的线程不能进行任何GUI调用。为了让它与GUI交互,您可以通过
Queue.Queue
发送输出(例如状态更新消息),并同时让主Tkinter线程定期监视这个Queue.Queue
(通过调用root.after
):相关问题 更多 >
编程相关推荐