简体   繁体   English

如何轻松避免Tkinter卡顿?

[英]How to easily avoid Tkinter freezing?

I developed a simple Python application doing some stuff, then I decided to add a simple GUI using Tkinter.我开发了一个简单的 Python 应用程序来做一些事情,然后我决定使用 Tkinter 添加一个简单的 GUI。

The problem is that, while the main function is doing its stuff, the window freezes.问题是,当主要的 function 正在做它的事情时,window 冻结了。

I know it's a common problem and I've already read that I should use multithreads (very complicated, because the function updates the GUI too) or divide my code in different function, each one working for a little time.我知道这是一个常见问题,我已经读到我应该使用多线程(非常复杂,因为 function 也会更新 GUI)或将我的代码分成不同的 function,每个工作一段时间。 Anyway I don't want to change my code for such a stupid application.无论如何,我不想为这样一个愚蠢的应用程序更改我的代码。

My question is: is it possible there's no easy way to update my Tkinter window every second?我的问题是:是否有可能没有简单的方法来每秒更新我的 Tkinter window? I just want to apply the KISS rule!我只想应用 KISS 规则!

I'll give you a pseudo code example below that I tried but didn't work:我将在下面给你一个我试过但没有用的伪代码示例:

    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()

It simply will execute refresh only once, and I cannot understand why.它只会执行一次刷新,我不明白为什么。

Thanks a lot for your help.非常感谢你的帮助。

Tkinter is in a mainloop . Tkinter 处于mainloop Which basically means it's constantly refreshing the window, waiting for buttons to be clicked, words to be typed, running callbacks, etc. When you run some code on the same thread that mainloop is on, then nothing else is going to perform on the mainloop until that section of code is done.这基本上意味着它不断刷新窗口,等待单击按钮,输入单词,运行回调等。当您在主mainloop所在的同一线程上运行一些代码时, mainloop不会执行任何其他mainloop直到那段代码完成。 A very simple workaround is spawning a long running process onto a separate thread.一个非常简单的解决方法是将长时间运行的进程派生到一个单独的线程上。 This will still be able to communicate with Tkinter and update it's GUI (for the most part).这仍然能够与 Tkinter 通信并更新它的 GUI(在大多数情况下)。

Here's a simple example that doesn't drastically modify your psuedo code:这是一个简单的示例,它不会彻底修改您的伪代码:

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 answer goes into some detail on mainloop and how it blocks your code.这个答案详细介绍了mainloop以及它如何阻止您的代码。

Here's another approach that goes over starting the GUI on it's own thread and then running different code after.这是另一种方法,它在它自己的线程上启动 GUI,然后运行不同的代码。

'Not responding' problem can be avoided using Multithreading in python using the thread module.在 python 中使用线程模块使用多线程可以避免“无响应”问题。

If you've defined any function, say combine() due to which the Tkinter window is freezing, then make another function to start combine() in background as shown below:如果您已经定义了任何 function,比如combine() ,因为 Tkinter window 正在冻结,然后创建另一个 function 以在后台启动combine() ,如下所示:

 import threading def combine(): ... def start_combine_in_bg(): threading.Thread(target=combine).start()

Now instead of calling combine() , you have to call start_combine_in_bg() I did this and now my window is not freezing so I shared it here.现在不是调用combine() ,而是必须调用start_combine_in_bg()我这样做了,现在我的 window 没有冻结,所以我在这里分享它。 Remember you can run only one thread at a time.请记住,您一次只能运行一个线程。

Have a look for reference: stackoverflow - avoid freezing of tkinter window using one line multithreading code看看参考: stackoverflow - avoid freezing of tkinter window using one line multithreading code

Here's how I managed to work around this issue (maybe it's quite dirty I don't know):这是我设法解决这个问题的方法(也许我不知道它很脏):

Whenever I update my tkinter window through the doingALotOfStuff() function, I call myTk.update() .每当我更新我tkinter透过窗户doingALotOfStuff()函数,我叫myTk.update()

It avoids freezing for me.它避免了我的冻结。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM