Tkinter代码在没有mainloop,更新或之后运行

问题描述 投票:-1回答:1

我一直在尝试使用tkinter来制作一个gui来从这些文件中选择一些excel文件和工作表。

我在python方面有很多经验,但我可能会说tkinter的新手。

我编写的用于选择文件的代码如下所示(错别字可能是因为我无法在机器上访问这些文件所在的互联网,所以我在这里输入它)。

我的问题是关于mainloop(),更新函数和after()。我的代码末尾有mainloop(),但是我的程序在完成它的工作后不会终止(即终端会保留)。所以我删除了mainloop(),现在它完美地运行,没有任何mainloop()update()after()调用。

我真的不明白这一点,我真的很想。我得到mainloop()停止代码进行直到根关闭,但我认为没有mainloop()没有任何东西会显示,并且此代码确实等待用户关闭窗口然后继续。

我也想知道如果我没有mainloop(或类似),代码仍然很好,无论我是否在root.destroy()类的末尾有App(在代码中注释)。我也没有。

这些信息将帮助我在将来制作更好,更正确的代码,并希望能够改进这一代码。仅供参考,我在各处寻找答案,找不到一个,至少有一个我能理解的。谢谢一堆。

这是我能想到的最小的代码。

代码(原帖子编辑):

import tkinter as tk
from tkinter import ttk

class App:
    def __init__(self, parent):
        self.root = parent
        self.root.withdraw()

        tl = tk.Toplevel(parent)
        b = ttk.Button(tl, text="Test widget")
        b.grid()
        tl.wait_window()

        # This line does not change how the code functions at all
        #self.root.destroy()

    def run(self):
        # Whether or not this is a function in the class or called globally doesn't matter.
        self.root.mainloop()


if __name__ == "__main__":
    root = tk.Tk()
    app = App(root)

    # This is the mainloop() call. If I include it, the program does not close after
    # running the code in App.__init__. Without it, it runs perfectly.
    # app.run()
python tkinter python-3.6
1个回答
0
投票

mainloop为您的tk.Tk()应用程序输入事件监听循环。

您应该在每个tkinter应用程序中只使用Tk()创建一个对象。

现在,这个循环将“全局”侦听GUI事件,并将调用您注册的回调(事件处理程序)。在mainloop调用之前的代码将运行,但在您调用之前,屏幕上不会显示或更新任何内容。在此之前,没有事件(用户输入,鼠标移动,键盘等)将排队并响应。但是小部件已创建和配置,但尚未显示。如果你在没有进入主循环的情况下调用root.update(),你最终会看到窗口闪烁并消失,因为一切都在运行,你强制窗口刷新,但突然程序结束。

所以配置你的GUI,最后总是运行root.mainloop()

现在当你调用wait_window时,你正在创建一个本地事件循环(如果它正在运行则阻塞主循环)。关于wait_window的完美解释,Brian见here

你怎么了,你的应用程序很高兴与你的本地事件循环一起运行,但没有mainloop。这将是一件奇怪的事情。即使你正在布莱恩解释一个模态窗口,你想在窗口关闭后“返回”到主循环。

至于after方法,它只是注册一个回调函数,在你选择的时间之后运行,或者在mainloop因为空闲之后运行after_idle(没有更多的东西要刷新,队列中没有事件......,也要尽快考虑)。如果你想以同样的方式重新运行该函数,它应该在返回之前重新注册afterafter_idle

所以总是使用你的mainloop()结束调用 - 或者我应该说事件循环开始调用:)

编辑:

此外,不要在代码中执行缓慢或可能阻塞循环的操作,例如调用sleep或任何其他阻塞函数。这将冻结GUI,直到块结束。

© www.soinside.com 2019 - 2024. All rights reserved.