Темы и tkinter python 3

Я слышал, что потоки в Python нелегко обрабатывать, и они становятся более запутанными с tkinter.

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

Упрощенная версия кода:

import time, threading from tkinter import * from tkinter import messagebox finish = False class tkinterGUI(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): global finish #Main Window self.mainWindow = Tk() self.mainWindow.geometry("200x200") self.mainWindow.title("My GUI Title") #Label lbCommand = Label(self.mainWindow, text="Hello world", font=("Courier New", 16)).place(x=20, y=20) #Start self.mainWindow.mainloop() #When the GUI is closed we set finish to "True" finish = True class InfiniteProcess(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): global finish while not finish: print("Infinite Loop") time.sleep(3) GUI = tkinterGUI() GUI.start() Process = InfiniteProcess() Process.start() 

Когда я нажимаю кнопку закрытия (в правом верхнем углу), в консоли появляется следующая ошибка:

Tcl_AsyncDelete: обработчик async удален из-за неправильного потока

Я не знаю, почему это происходит или что это значит, пожалуйста, помогите!

2 Solutions collect form web for “Темы и tkinter python 3”

Все команды Tcl должны происходить из одного потока . Из-за зависимости tkinter от Tcl, как правило, необходимо сделать все tkinter gui из одного потока. Проблема возникает из-за mainWindow что mainWindow в потоке tkinterGui , но – потому что mainWindow является атрибутом tkinterGui – не уничтожается до tkinterGui пор, пока tkinterGui будет уничтожен в основном потоке.

Проблему можно избежать, если не сделать mainWindow атрибутом tkinterGui – т.е. изменить self.mainWindow на mainWindow . Это позволяет mainWindow , когда метод run заканчивается в потоке tkinterGui . Однако часто вы можете полностью исключить потоки, используя вместо этого вызовы mainWindow.after :

 import time, threading from tkinter import * from tkinter import messagebox def infinite_process(): print("Infinite Loop") mainWindow.after(3000, infinite_process) mainWindow = Tk() mainWindow.geometry("200x200") mainWindow.title("My GUI Title") lbCommand = Label(mainWindow, text="Hello world", font=("Courier New", 16)).place(x=20, y=20) mainWindow.after(3000, infinite_process) mainWindow.mainloop() 

Если вы хотите определить GUI внутри класса, вы все равно можете это сделать:

 import time, threading from tkinter import * from tkinter import messagebox class App(object): def __init__(self, master): master.geometry("200x200") master.title("My GUI Title") lbCommand = Label(master, text="Hello world", font=("Courier New", 16)).place(x=20, y=20) def tkinterGui(): global finish mainWindow = Tk() app = App(mainWindow) mainWindow.mainloop() #When the GUI is closed we set finish to "True" finish = True def InfiniteProcess(): while not finish: print("Infinite Loop") time.sleep(3) finish = False GUI = threading.Thread(target=tkinterGui) GUI.start() Process = threading.Thread(target=InfiniteProcess) Process.start() GUI.join() Process.join() 

или даже проще, просто используйте основной поток для запуска GUI mainloop:

 import time, threading from tkinter import * from tkinter import messagebox class App(object): def __init__(self, master): master.geometry("200x200") master.title("My GUI Title") lbCommand = Label(master, text="Hello world", font=("Courier New", 16)).place(x=20, y=20) def InfiniteProcess(): while not finish: print("Infinite Loop") time.sleep(3) finish = False Process = threading.Thread(target=InfiniteProcess) Process.start() mainWindow = Tk() app = App(mainWindow) mainWindow.mainloop() #When the GUI is closed we set finish to "True" finish = True Process.join() 

Исправление здесь прост, но трудно обнаружить:

Вызовите mainWindow.quit() сразу после mainwindow.mainloop() , так что очистка происходит в том же потоке, что и тот, который создал пользовательский интерфейс tk, а не на основной поток при выходе из python.

  • Python: функция принимает 1 позиционный аргумент, но 2 даны, как?
  • Цвет окна по умолчанию Tkinter и шестнадцатеричные цветовые коды
  • Функция закрытия окна в Tkinter
  • Есть ли способ удалить ярлык или кнопку из окна tkinter, а затем добавить его обратно?
  • Как закрыть окно Tkinter нажатием кнопки?
  • Python 3 Tkinter - Создать текстовый виджет, покрывающий 100% ширину с сеткой
  • Ограничение входа в виджет tk
  • Поднимите и поднимите холст поверх холста в tkinter
  • Python - лучший язык программирования в мире.