Как предотвратить застревание потока в основном цикле Tkinters? ⇐ Python
-
Anonymous
Как предотвратить застревание потока в основном цикле Tkinters?
Я новичок в Python, поэтому извините, если я не высказался номинально. У меня есть поток под названием «thread1», который циклически увеличивает переменную «num» на 1 так быстро, как только может. Каждый раз, когда он увеличивает «num», он затем устанавливает виджет в моем приложении, используя функцию «update_widget», расположенную в моем классе «Приложение». Проблема в том, что когда я вызываю «очистку», поток застревает и никогда не вызывает сценарий «end_thread», как следует. Это означает, что мое приложение ожидает, пока это произойдет, и поэтому зависает. Ниже представлена упрощенная версия моего проекта в одном скрипте. Этот скрипт воссоздает мою проблему.
# test7.py импортировать tkinter как tk импорт потоков от времени импортировать сон класс Thread1: def __init__(self, a, d): self.app = а self.data = d самостоятельный = Ложь защита end_thread (сам): print("Конечная тема") self.ended = Истина поднять SystemExit цикл защиты (сам): print("Инициализировать цикл") число = 0 пока правда: если self.data.end: self.end_thread() число += 1 self.app.update_widget(str(num)) класс приложения(tk.Tk): защита __init__(self, d): супер().__init__() self.data = d self.widget = tk.Entry(self) self.widget.pack() Защиту update_widget (я, текст): print("Обновление виджета") self.widget.delete(0, tk.END) self.widget.insert(0, текст) Данные класса: защита __init__(сам): self.end = Ложь очистка защиты(): печать("Закрытие") data.end = Истина пока не thread1_class.ended: спать(0.2) еще: поднять SystemExit print("Имя: ", __name__) если __name__ == "__main__": данные = Данные() приложение = Приложение (данные) thread1_class = Thread1 (приложение, данные) thread1 = threading.Thread(target=thread1_class.loop) поток1.start() app.protocol("WM_DELETE_WINDOW", очистка) приложение.mainloop() Я пробовал:
[*]Удаление виджета перед включением data.end. [*]Добавление переменной для остановки обновления перед включением data.end. [*]Выполнение «очистки» в другом потоке. [*]Создание потока внутри класса «Приложение», который будет проверять изменения данных.
В ходе тестирования я понял, что причина зависания потока заключается в том, что основной поток недоступен для обновления виджетов, поскольку он находится в цикле while, ожидая завершения подпотока. Я не знаю, как это обойти.
Я новичок в Python, поэтому извините, если я не высказался номинально. У меня есть поток под названием «thread1», который циклически увеличивает переменную «num» на 1 так быстро, как только может. Каждый раз, когда он увеличивает «num», он затем устанавливает виджет в моем приложении, используя функцию «update_widget», расположенную в моем классе «Приложение». Проблема в том, что когда я вызываю «очистку», поток застревает и никогда не вызывает сценарий «end_thread», как следует. Это означает, что мое приложение ожидает, пока это произойдет, и поэтому зависает. Ниже представлена упрощенная версия моего проекта в одном скрипте. Этот скрипт воссоздает мою проблему.
# test7.py импортировать tkinter как tk импорт потоков от времени импортировать сон класс Thread1: def __init__(self, a, d): self.app = а self.data = d самостоятельный = Ложь защита end_thread (сам): print("Конечная тема") self.ended = Истина поднять SystemExit цикл защиты (сам): print("Инициализировать цикл") число = 0 пока правда: если self.data.end: self.end_thread() число += 1 self.app.update_widget(str(num)) класс приложения(tk.Tk): защита __init__(self, d): супер().__init__() self.data = d self.widget = tk.Entry(self) self.widget.pack() Защиту update_widget (я, текст): print("Обновление виджета") self.widget.delete(0, tk.END) self.widget.insert(0, текст) Данные класса: защита __init__(сам): self.end = Ложь очистка защиты(): печать("Закрытие") data.end = Истина пока не thread1_class.ended: спать(0.2) еще: поднять SystemExit print("Имя: ", __name__) если __name__ == "__main__": данные = Данные() приложение = Приложение (данные) thread1_class = Thread1 (приложение, данные) thread1 = threading.Thread(target=thread1_class.loop) поток1.start() app.protocol("WM_DELETE_WINDOW", очистка) приложение.mainloop() Я пробовал:
[*]Удаление виджета перед включением data.end. [*]Добавление переменной для остановки обновления перед включением data.end. [*]Выполнение «очистки» в другом потоке. [*]Создание потока внутри класса «Приложение», который будет проверять изменения данных.
В ходе тестирования я понял, что причина зависания потока заключается в том, что основной поток недоступен для обновления виджетов, поскольку он находится в цикле while, ожидая завершения подпотока. Я не знаю, как это обойти.