Quand j'ai démarré tkinter dans un autre thread, j'ai eu du mal à terminer le programme normalement, donc je partagerai les informations.
tkinter boucle le dessin et le traitement des événements en appelant mainloop ()
.
Vous pouvez terminer mainloop ()
en appelant destroy ()
dans tkinter.
Après cela, lorsque le thread se termine, tkinter est également détruit.
Cependant, si destroy ()
était appelé depuis un autre thread ou si le widget tkinter (partie GUI) était toujours assigné à la variable d'instance, le programme ne pouvait pas se terminer normalement.
Je vais expliquer avec un exemple de programme.
import time
import threading
import tkinter as tk
class GUI:
def start(self):
self.running = True
self.window = tk.Tk()
self.window.title("Sample")
self.window.geometry('320x240')
self.value = tk.StringVar()
entry = tk.Entry(textvariable=self.value)
entry.pack()
self.window.after(1000, self._check_to_quit)
self.window.mainloop()
# need to delete variables that reference tkinter objects in the thread
del self.value
del self.window
def _check_to_quit(self):
if self.running:
self.window.after(1000, self._check_to_quit)
else:
self.window.destroy()
def quit(self):
self.running = False
def main():
gui = GUI()
thread = threading.Thread(target=gui.start)
thread.start()
time.sleep(2)
for i in 1, 2, 3, 'Dar!!':
gui.value.set(i)
time.sleep(1)
gui.quit()
thread.join()
if __name__ == '__main__':
main()
main ()
crée une interface graphique et un sous-thread, et le sous-thread démarre gui.start ()
.
Lors de la fin du processus main ()
, appelez gui.quit ()
pour définir l'indicateur de fin, le sous-thread vérifie toutes les 1 seconde et le sous-thread lui-même appelle destroy ()
. Je le fais.
L'appel de gui.window.destroy ()
directement au lieu de ce gui.quit ()
a provoqué une boucle infinie.
Je ne pouvais pas entendre CTRL + C
, et je n'avais pas d'autre choix que de forcer l'arrêt (vidage de mémoire) avec CTRL + \
.
Dans le sous-thread, après avoir quitté mainloop ()
, la variable d'instance est del
.
Si ce traitement «del» n'est pas effectué, le programme peut se terminer anormalement (vidage de mémoire) ou générer un message d'erreur sans fin.
Expérimentez ce qui se passe en faisant gui.window.destroy ()
directement depuis main ()
ou en commentant le traitement del de la variable d'instance.
Soyez prudent lorsque vous utilisez tkinter et threads ensemble.