Les deux méthodes suivantes sont présentées pour le traitement d'exécution périodique dans tkinter.
--Lors de l'utilisation du module de filetage --Lors de l'utilisation du module de planification
Pour un traitement simple, il n'est pas nécessaire d'utiliser le module de threading ou le module de planification, mais pour un traitement lourd, l'opération de tk lui-même (appui sur un bouton / déplacement de l'écran, etc.) devient lourde. Par conséquent, même si cela pose problème, il peut être préférable de l'implémenter par la méthode ci-dessus.
Voici l'exemple de code. C'est un programme qui augmente la valeur de "self.label" de 1. Si vous souhaitez le faire, vous pouvez l'exécuter régulièrement en millisecondes. Comme il s'agit de python, la précision du temps n'est pas si bonne, mais si vous n'avez pas à vous soucier autant de la précision du temps, cela suffit.
import tkinter as tk
import threading
class GUI(tk.Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
master.geometry("300x300")
master.title("Test")
self.count = 0 #Tampon des valeurs définies dans l'étiquette
self.test = tk.Frame(self.master)#Ce n'est pas nécessaire, mais j'ai créé un autre cadre pour gérer l'écran.
self.test.pack()
self.label = tk.Label(self.test)
self.label.pack()
self.label["text"] = str(self.count) #Initialiser la valeur de l'étiquette
self.timeEvent()#Activation de la minuterie
#Fonction de démarrage de la minuterie
def timeEvent(self):
th = threading.Thread(target=self.update)#Instanciation de thread
th.start()#Début du fil
self.after(1000, self.timeEvent)#Appelez maintenant la fonction récursivement
#Entité de traitement de thread
def update(self):
self.count += 1
print(self.count) #Message de débogage
self.label["text"] = str(self.count) #Mettre à jour la valeur de l'étiquette
if __name__ == "__main__":
gui = tk.Tk()
app = GUI(master = gui)
app.mainloop()
Si vous voulez plus de précision du temps, le processus sera un peu compliqué, mais vous pouvez écrire comme suit. Je pense que ce sera deux fois plus précis dans le temps, mais ce sera un peu moins lisible.
import tkinter as tk
import threading
import time
class GUI(tk.Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
master.geometry("300x300")
master.title("Test")
self.count = 0
self.test = tk.Frame(self.master)
self.test.pack()
self.label = tk.Label(self.test)
self.label.pack()
self.label["text"] = str(self.count)
self.buftime = time.time()#Initialisation du minuteur
self.timeEvent()
def timeEvent(self):
tmp = time.time()
if(tmp - self.buftime) >= 1: #Quand 1 seconde s'est écoulée
th = threading.Thread(target=self.update)
th.start()
print(tmp - self.buftime)
self.buftime = tmp
self.after(1, self.timeEvent)
def update(self):
self.count += 1
self.label["text"] = str(self.count)
if __name__ == "__main__":
gui = tk.Tk()
app = GUI(master = gui)
app.mainloop()
Vous pouvez faire de même avec le module «planning». Cependant, cela doit être installé avec pip. De plus, il semble que l'exécution périodique en millisecondes ne puisse pas être effectuée dans la plage examinée.
Si c'est en quelques secondes, je pense que c'est plus lisible, donc il vaut peut-être mieux le sélectionner en fonction de l'objectif.
pip install schedule
import tkinter as tk
import schedule
class GUI(tk.Frame):
def __init__(self,master = None):
super().__init__(master)
self.master = master
master.geometry("300x300")
master.title("Test")
self.count = 0
self.test = tk.Frame(self.master)
self.test.pack()
self.label = tk.Label(self.test)
self.label.pack()
self.label["text"] = str(self.count)
schedule.every(1).seconds.do(self.update)#Ajouter une tâche à planifier
self.sc()
def sc(self): #Vérifiez régulièrement l'état de la tâche avec le module de planification
schedule.run_pending()
self.after(1, self.sc) #Exécuter récursivement
def update(self):
self.count += 1
print(self.count)
self.label["text"] = str(self.count)
if __name__ == "__main__":
gui = tk.Tk()
app = GUI(master = gui)
app.mainloop()
Le module "threading" de Python ne s'exécute qu'une seule fois par déclaration d'instance. Ceci est une spécification du module de filetage. Un exemple est présenté ci-dessous.
error.py
import threading
th = threading.Thread(target=self.update)
th.start()
th.start() #← Erreur ici "Erreur d'exécution": threads can only be started once」