如何轻松避免Tkinter冻结?

时间:2017-02-23 17:11:09

标签: python user-interface tkinter

我开发了一个简单的Python应用程序,然后我决定使用Tkinter添加一个简单的GUI。

问题在于,虽然主要功能是做它的东西,但窗口会冻结。

我知道这是一个常见的问题,我已经读过我应该使用多线程(非常复杂,因为该函数也会更新GUI)或者将我的代码分成不同的函数,每个函数都运行一段时间。 无论如何,我不想为这样一个愚蠢的应用程序更改我的代码。

我的问题是:是否有可能没有简单的方法来每秒更新我的Tkinter窗口?我只是想申请KISS规则!

我将在下面给你一个伪代码示例,但我没有尝试但是没有用:

    class Gui:
        [...]#costructor and other stuff

        def refresh(self):
            self.root.update()
            self.root.after(1000,self.refresh)

        def start(self):
            self.refresh()
            doingALotOfStuff()

    #outside
    GUI = Gui(Tk())
    GUI.mainloop()

它只会执行一次刷新,我无法理解为什么。

非常感谢你的帮助。

2 个答案:

答案 0 :(得分:5)

Tkinter位于mainloop。这基本上意味着它不断刷新窗口,等待按钮被点击,要输入的单词,运行回调等等。当你在mainloop所在的同一个线程上运行一些代码时,什么也没有else将在mainloop上执行,直到该部分代码完成。一个非常简单的解决方法是将一个长时间运行的进程生成到一个单独的线程上。这仍然可以与Tkinter通信并更新它的GUI(大部分)。

这是一个简单的示例,它不会彻底修改您的伪代码:

import threading

class Gui:
    [...]#costructor and other stuff

    def refresh(self):
        self.root.update()
        self.root.after(1000,self.refresh)

    def start(self):
        self.refresh()
        threading.Thread(target=doingALotOfStuff).start()

#outside
GUI = Gui(Tk())
GUI.mainloop()

This回答详细介绍了mainloop以及它如何阻止您的代码。

Here's另一种方法是在其自己的线程上启动GUI,然后运行不同的代码。

答案 1 :(得分:0)

这是我设法解决这个问题的方法(也许我不知道它很脏):

每当我通过 tkinter 函数更新我的 doingALotOfStuff() 窗口时,我都会调用 myTk.update()

它避免了我冻结。