# Autres langages > Python > GUI >  execution periodique avec GUI

## babsh

Bonjour,
je recherche un moyen simple dexecuter periodiquement (toutes les x min.) une commande. Lexecution periodique doit commencer quand lutilisateur appuie sur un bouton "commencer" et sarreter lorsquil appuie sur un bouton "terminer".

Jai bien reussi avec Tkinter de Python a faire les boutons, mais je ne sais pas comment faire lexecution periodique qui sarreterait quand on appuie sur un bouton.
Quelquun pourrait-il me dire comment faire? Si possible sans trop consommer de ressource.

----------


## PauseKawa

Bonjour,

Pas compris: Si c'est priodique pas besoin de bouton "commencer" /"terminer". Cela se passe via un daemon/thread etc... Et pas besoin de GUI.
Pouvez vous prciser ce que vous voulez faire ?
Pour ce qui est de Tkinter avez vous vus que le Widget Button a une option command ? C'est pour spcifier une fonction a excuter.

@+

----------


## PauseKawa

Voila pour la partie GUI


```

```

Pour le reste dans l'attente de vous lire.

@+

----------


## VinsS

Salut,

Moi, je comprends plutt que le bouton sert simplement  mettre en marche le timer et ensuite  le stopper.

Si c'est bien cela, il suffit de montrer le code du timer, il doit bien y avoir un moyen de l'arrter.

----------


## babsh

Ce que j entends par periodique cest une repetition a intervalle regulier dune commande jusqua ce que lutilisateur dise: stop. Linformation stop peut etre donne par GUI, ce nest effectivement pas obligatoire, mais plus pratique.

Je pourrais lancer une boucle infinie genre:

while true
ma commande
pause x min

et "killer" le processus quand je veux larreter, mais ce nest pas tres elegant comme methode!

En fait jai ecrit un script python qui actualise une base de donnee. Jaimerai pouvoir lancer regulierement (toutes les x min.) ce script quand jai besoin davoir cette base de donnee toujours actualisee. Quand je nen ai plus besoin, jaimerais pouvoir arreter lactualisation de ma base de donnee.

----------


## VinsS

C'est bien ce que j'avais copris, mais ton 'timer' tu l'as crit comment ?

Un thread ? threading.Timer ?

Une boucle while, a m'tonnerait.

Bref, on veut du code.

----------


## wiztricks

Salut

Avec Tkinter, vous avez la mthode .after(delay, callback) qui permet d'appeler la fonction "callback" aprs "delay" millisecondes.

La discussion rcente montre comment utiliser la chose pour "rpter" l'opration "tant que".

La mthode .after retourne un identifiant qui pourra tre pass en paramtre  la mthode .cancel pour arrter le monstre.

Ces mthodes .after, .cancel sont disponibles pour tous les widgets Tk.
Vous pouvez aussi lire la discussion qui traite de ce sujet.

Ces indications devrait vous permettre d'crire un premier code et de rler sur les aspects que vous ne comprenez pas.

- W

----------


## babsh

La methode .after(delay, callback) marche nickel! Par contre je narrive pas a larreter avec le .cancel. Comment utilise-t-on le .cancel? Auriez-vous un exemple?
Voici un extrait de mon code:



```

```

----------


## wiztricks

Dsol, j'ai m...
Il faut utiliser .after_cancel et non .cancel (que je ne sais mme pas ce que c'est):

Un exemple post, il y a longtemps:


```

```

- W

----------


## babsh

Merci ca marche nickel!

Mon code si ca interesse quelquun:



```

```

----------


## PauseKawa

Bonjour,

Deux ou trois petites choses qui me sont venues  l'esprit  la lecture du code:

Ne mlanger pas tabulations et espaces.

Pas besoin de global puisque vous avez self.

Utilisez parent.destroy et non f.quit.

Le fait d'utiliser le mme nom pour tout vos Widgets Button fait vous crasez la rfrence  chaque fois. Mais au fait: Pourquoi la garder puisque seul command nous intresses.

padx=0,pady=0 ne sert  rien. De mme ici les side= puisque .pack() le places de haut en bas. Mais bon, cela ne gne en rien.

Lintrt du Label hors de la Frame ? Et lintrt de la Frame en fait puisque .pack() positionne les Widgets de haut en bas ?

root.after(1000, self.update_loop) ? self.parent.after(1000, self.update_loop) En fait.



```

```

Je vois un import threading donc je pense que c'est utile pour votre code complet: Attention avec Tkinter qui n'est pas threadsave.

Astuce: Lorsque vous utilisez les mmes options de gomtrie pour un groupe de Widget vous pouvez utiliser un dico.

Lintrt de la classe ici ? A la limite si cela drive de Tk.

if self.counter_id est source  erreur (AttributeError) si vous cliquez sur stop avant. Soit vous utilisez hasattr, soit (le plus simple) vous donnez une valeur  self.counter_id.


```

```

Petit modif pour rendre l'exemple compatible Python 2/3



```

```

Une autre astuce au passage pour les Widgets identiques



```

```

Mais en fait ici pas besoin d'une classe



```

```

@+ et bon code

Edit: Bonus gomtrique
geometry = {'padx': 10, 'pady': 10, 'fill': tk.BOTH}

Edit: Erreur de tabulation.

----------


## babsh

En fait mon code c est de la recupe de codes que j'ai trouve sur internet. D'ou toutes les incoherences. Je debute en python, c'est l'un de mes premiers codes.
En tous cas, merci a tous pour votre aide!

Juste une petite derniere question. L'execution de la boucle periodique n'est en fait pas exactement periodique.

La periode d'execution de la fonction update_loop:


```

```

est en faite de 1 seconde + le temps d'execution de:


```
print(entry.get())
```

Bon dans ce cas, l'execution de print est quasi instantannee, donc ca n'a pas d'importance. Mais j'utilise ce code pour lancer un autre python (actualiser une base de donnee), dont le temps d'execution est non negligeable et irregulier. La meilleure solution que j'ai trouve pour que la periode d'execution de la fonction update_loop soit independante de la duree de l'application que je lance (ici print(entry.get()) ), c'est de mettre le root.after avant le print:


```

```

Je voulais juste avoir votre avis sur cette astuce. Est-ce correcte? Bon chez moi ca a l'air demarche.

----------


## PauseKawa

C'est bien cela.
Je rajouterais que si vous modifiez quelque chose il n'est sans doute pas bon de lancer le mme traitement deux fois en mme temps, dans le cas ou le premier n'est pas fini. Comprendre que votre traitement doit 'signaler' qu'il a fini avant d'en faire un autre.


```

```

----------

