Tkinter:一个或多个主循环?

时间:2011-09-21 12:42:48

标签: python tkinter

我有一个已经很大的Tkinter程序,所以我有一个 init 文件,其中定义了root = Tk()窗口(基本上包含Text小部件还有一些其他的东西),更多的代码,并持续调用mainloop()函数。

一切正常,直到我需要在<{em> 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程序通过用户点击和交互等驱动的逻辑工作。

在这里,我需要一系列提升窗口&gt;做的事情&gt;销毁窗口&gt;主循环

2 个答案:

答案 0 :(得分:1)

在程序初始化之后,您需要调用mainloop一次是正确的。这是启动事件循环所必需的,这是Windows绘制自己,响应事件等所必需的。

您可以做的是将初始化分为两部分。第一个 - 创建等待窗口 - 在启动事件循环之前发生。第二个 - 执行剩余的初始化 - 在事件循环开始后发生。您可以通过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()

答案 1 :(得分:0)

你应该使用Tkinter的方法来运行asyncore的循环函数,但你应该使用asyncore.poll(0)而不是asyncore.loop()。如果每隔x ms调用一次函数asyncore.poll(0),它就不再对Tkinter的主循环产生影响。