Tkinter:一个或多个主循环?
我有一个已经很大的 Tkinter
程序,所以我有一个 init 文件,在里面定义了 root = Tk()
窗口(基本上包含一个 Text
组件和一些其他东西),还有一些代码,最后是调用 mainloop()
函数。
一切都正常,直到我需要在 mainloop
之前调用一个过程,并且我想在开始时弹出一个 wait
窗口,等过程结束后再关闭它。
我写了类似这样的代码:
msg = Message(root, text='wait a few seconds...')
msg.pack()
但是这样不行,也不能工作,因为 mainloop()
还没有被调用!
如果我改成这样:
msg = Message(root, text='wait a few seconds...')
msg.pack()
mainloop()
程序在第一个 mainloop
这里停住了,没法完成过程调用。
mainloop()
应该作为你程序的最后一行代码来使用,之后 Tkinter 程序就会根据用户的点击和互动来运行。
在这里,我需要一个顺序:弹出窗口 > 做事情 > 关闭窗口 > 进入主循环
2 个回答
0
你应该使用Tkinter的方法来运行asyncore的循环功能,但要用asyncore.poll(0)来代替asyncore.loop()。如果你每隔x毫秒调用一次asyncore.poll(0)这个函数,它就不会对Tkinter的主循环产生影响了。
1
你说得对,mainloop
这个方法需要在你的程序初始化完成后调用一次。这是为了启动事件循环,这样窗口才能自己绘制、响应各种事件等等。
你可以把初始化过程分成两个部分。第一部分是创建等待窗口,这个步骤是在启动事件循环之前完成的。第二部分是完成剩下的初始化,这个步骤是在事件循环启动后进行的。你可以通过 after
方法来安排第二个阶段的执行。
下面是一个简单的例子:
import Tkinter as tk
import time
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
# initialize Tkinter
tk.Tk.__init__(self, *args, **kwargs)
# hide main window
self.wm_withdraw()
# show "please wait..." window
self.wait = tk.Toplevel(self)
label = tk.Label(self.wait, text="Please wait...")
label.pack()
# schedule the rest of the initialization to happen
# after the event loop has started
self.after(100, self.init_phase_2)
def init_phase_2(self):
# simulate doing something...
time.sleep(10)
# we're done. Close the wait window, show the main window
self.wait.destroy()
self.wm_deiconify()
app = SampleApp()
app.mainloop()