Ответ 1
Все команды Tcl должны происходить из одного потока. Из-за tkinter
's
зависимости от Tcl, вообще необходимо сделать все выражения tkinter
gui
происходят из одного потока. Проблема возникает из-за того, что
mainWindow
создается в потоке tkinterGui
, но - потому что mainWindow
является атрибутом 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()