[tkinter] Déclencher une tâche toutes les 5 minutes
Fermémamiemando Messages postés 33081 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 27 avril 2024 - 5 sept. 2022 à 09:42
- [tkinter] Déclencher une tâche toutes les 5 minutes
- Deplacer barre de tache windows 11 - Guide
- Gestionnaire de tache - Guide
- Veuillez patienter quelques minutes avant de réessayer instagram ✓ - Forum Instagram
- Honor magic 5 pro vs s23 ultra - Guide
- Resultat loto 5/90 ✓ - Forum Excel
5 réponses
Modifié le 2 sept. 2022 à 12:05
Bonjour,
Voici un exemple minimal montrant comment tu peux planifier l'exécution d'une tâche toutes les 2 secondes à l'aide de la méthode after.
from tkinter import * root = Tk() def task(): print("hello") root.after(2000, task) # reschedule event in 2 seconds root.after(2000, task) root.mainloop()
Dans ton cas il faut simplement remplacer 2000 par 5 * 60 * 1000 = 300000 et ta boucle d'événement s'appelle master au lieu de root.
Note que si tu veux que ta fonction task soit paramétrée, le plus élégant est d'écrire un foncteur, c'est à dire un objet qui implémente la méthode __call__ (sans paramètre autre que self) et dont le constructeur reçoit les paramètres en question.
Voici un exemple de foncteur (instancié, puis appelé 3 fois). Comme tu peux le voir, une fois le foncteur instancié, il se comporte comme une fonction qui, conformément à la signature de __call__, ne prend pas de paramètre.
class Task(): def __init__(self, message): self.message = message self.interval = interval def __call__(self): print(self.message) task = Task("hello") task() # 1er appel task() # 2e appel task() # 3e appel
Maintenant, modifions un peu ce foncteur pour qu'il reçoive en paramètre l'intervalle de temps et qu'il se réenregistre dans la boucle d'événement à chaque fois qu'il est appelé. Le deux extraits de code précédents ainsi combinés permettent d'arriver à ceci :
from tkinter import * root = Tk() class Task(): def __init__(self, message, interval = 1000): self.message = message self.interval = interval def __call__(self): print(self.message) root.after(self.interval, self) interval = 2000 task = Task("hello", interval) root.after(interval, task) root.mainloop()
Tu notereras le second paramètre d'after devient self. En effet :
- self correspond à notre foncteur (qu'on a appelé task au niveau du programme principal) et qu'on peut appeler comme une callback sans paramètre.
- On ne doit/peut pas utiliser task dans __call__ car :
- task n'est pas encore déclaré
- même si elle était (genre en début de programme), il faut quand même utiliser self car dans le cas général, l'instance courante de Task n'est pas forcément nommée task.
Bonne chance
31 août 2022 à 23:15
Une boucle et l'utilisation de time.sleep ?
Modifié le 2 sept. 2022 à 12:51
Bonjour NHenry,
Une boucle et l'utilisation de time.sleep ?
- Non, il ne faut pas faire utiliser sleep dans une boucle d'événements (cf master.mainloop()), car sinon, tu gèles l'interface pendant toute la durée du sleep.
- Pour éviter ce problème, il faut enregistrer un événement que tu déclenches toutes les 5 minutes et que tu rattrapes dans une callback (voir message #3).
2 sept. 2022 à 13:39
Merci beaucoup, mais je suis débutant et je vois pas comment l'intégrer dans mon interface.,
je rame.
UN grand merci quand même, je vais faire des essais.
Modifié le 5 sept. 2022 à 09:42
Dans ton cas la tâche à répéter toutes les 5 minutes est la récupération du calendrier ce qui correspond à la ligne 14 et aux lignes 31 à 45 de ton programme initial. Comme le traitement est paramétré par l'url et frm5, on peut soit déclarer une fonction task après avoir déclaré url et frm5, soit utiliser un foncteur.
Je n'ai pas testé car je n'ai pas installé icalendar, mais dans l'idée ça ressemblerait à ça :
import io import locale import urllib.request from datetime import timedelta, datetime from tkinter import * import icalendar import pytz import recurring_ical_events URL = "https://calendar.google.com/calendar/ical/xxxx@gmail.com/private-6490b3915a6375657d88645094940586" \ INTERVAL = 300000 master = Tk() locale.setlocale(locale.LC_ALL, "fr_FR") master.attributes("-fullscreen", True) master.bind("<Escape>", lambda e: master.destroy()) master.config(background="black") frm5 = LabelFrame(master, text="Tatal", font="helvetica 15", fg="WHITE", bg="black", height=800, relief=GROOVE) frm5.place(x=20, y=250, width=500) def task(): # Agenda Tatal dat2 = datetime.now(pytz.timezone("Europe/Paris")) start_date = dat2.date() end_date = start_date + timedelta(days=30) "/basic.ics " ical_string = urllib.request.urlopen(URL).read() calendar = icalendar.Calendar.from_ical(ical_string) events = recurring_ical_events.of(calendar).between(start_date, end_date) pdr = True for event in events: pdr = False start = event["DTSTART"].dt duration = event["DTEND"].dt - event["DTSTART"].dt non = event["SUMMARY"] agd_tatal = Label(frm5, text=non + " " + start.strftime("%A %d %B %H %M"), font="Arial 16", fg="WHITE", bg="black") agd_tatal.pack(padx=10, pady=10) if pdr: agd_tatal = Label(frm5, text="Aucun rendez-vous aujourdhui", font="Arial 12", fg="WHITE", bg="black") agd_tatal.pack(padx=10, pady=10) # Re-run this task in INTERVAL milliseconds master.after(INTERVAL, task) master.after(INTERVAL, task) master.mainloop()
Bonne chance
2 sept. 2022 à 16:08
Merci,
ne marche pas, python me dit tasck "rename the element, Task " import this name"
3 sept. 2022 à 19:11
Peux-tu copier coller le message d'erreur exact ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question4 sept. 2022 à 08:57
Bonjour, et merci pour ton dévouement, voici l'erreur.
Traceback (most recent call last):
File "C:\Users\tatal\PycharmProjects\essais\essais.py", line 52, in <module>
task = Task(URL, frm5, INTERVAL)
NameError: name 'Task' is not defined. Did you mean: 'task'?
5 sept. 2022 à 09:42
Ah c'est ma faute : il y avait une ligne incorrecte qui traînait dans le message #5, je l'ai corrigé. Peux-tu réessayer ?