如何轻松避免 Tkinter 冻结? [英] How to easily avoid Tkinter freezing?

查看:38
本文介绍了如何轻松避免 Tkinter 冻结?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一个简单的 Python 应用程序来做一些事情,然后我决定使用 Tkinter 添加一个简单的 GUI.

I developed a simple Python application doing some stuff, then I decided to add a simple GUI using Tkinter.

问题在于,当 main 函数执行其操作时,窗口会冻结.

The problem is that, while the main function is doing its stuff, the window freezes.

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

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. Anyway I don't want to change my code for such a stupid application.

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

My question is: is it possible there's no easy way to update my Tkinter window every second? I just want to apply the KISS rule!

我会在下面给你一个我试过但没有用的伪代码示例:

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.

非常感谢您的帮助.

推荐答案

Tkinter 在 mainloop 中.这基本上意味着它不断刷新窗口,等待点击按钮,输入单词,运行回调等.当你在 mainloop 所在的同一线程上运行一些代码时,就没有别的了将在 mainloop 上执行,直到该部分代码完成.一个非常简单的解决方法是将长时间运行的进程派生到一个单独的线程上.这仍然能够与 Tkinter 通信并更新它的 GUI(在大多数情况下).

Tkinter is in a 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. 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).

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

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

这个答案详细介绍了 mainloop 以及它如何阻止您的代码.

This answer goes into some detail on mainloop and how it blocks your code.

这是另一种方法,它在自己的线程上启动 GUI,然后运行不同的代码.

Here's another approach that goes over starting the GUI on it's own thread and then running different code after.

这篇关于如何轻松避免 Tkinter 冻结?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆