Как легко избежать замерзания Tkinter?

Я разработал простое приложение на Python, а потом решил добавить простой графический интерфейс с использованием Tkinter.

Проблема в том, что пока основная функция выполняет свои функции, окно зависает.

Я знаю, что это общая проблема, и я уже читал, что я должен использовать многопоточность (очень сложная, потому что функция также обновляет графический интерфейс) или разделять мой код на разные функции, каждая из которых работает в течение некоторого времени. Во всяком случае, я не хочу менять свой код для такого глупого приложения.

У меня вопрос: возможно ли, что нет простого способа обновлять окно 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()

Он просто выполнит обновление только один раз, и я не могу понять, почему.

Большое спасибо за вашу помощь.

4 ответа

Ткинтер находится в mainloop, Что в основном означает, что оно постоянно обновляет окно, ждет нажатия кнопок, набираемых слов, выполнения обратных вызовов и т. Д. Когда вы запускаете некоторый код в том же потоке, который mainloop включен, то больше ничего не будет выполнять на mainloop пока этот раздел кода не будет сделан. Очень простой обходной путь - создание длинного процесса в отдельном потоке. Это все еще будет в состоянии общаться с Tkinter и обновлять его GUI (по большей части).

Вот простой пример, который радикально не изменяет ваш код psuedo:

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 и как это блокирует ваш код.

Вот еще один подход, который заключается в запуске GUI в его собственном потоке и последующем запуске другого кода.

Проблему «не отвечает» можно избежать, используя многопоточность в Python с помощью модуля потока.

Если вы определили какую-либо функцию, скажем, из-за которой окно Tkinter зависает, тогда заставьте другую функцию запускаться в фоновом режиме, как показано ниже:

       import threading
def combine():
    ...

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

Теперь вместо звонка ты должен позвонить Я сделал это, и теперь мое окно не замерзает, поэтому я поделился им здесь. Помните, что вы можете запускать только один поток за раз.

Посмотрите ссылку: stackoverflow - избегайте зависания окна tkinter с использованием однострочного многопоточного кода

Вот как мне удалось обойти эту проблему (возможно, она довольно грязная, я не знаю):

Всякий раз, когда я обновляю свой tkinter окно через doingALotOfStuff() функция, я вызываю myTk.update().

Для меня это помогает избежать замерзания.

Лучшее, что вы можете сделать для решения этой проблемы с зависанием, - это использовать многопоточность. Самый простой способ сделать это я опубликовал в своем ответе ранее здесь:окно Tkinter говорит (не отвечает), но код работает

Другие вопросы по тегам