10
votes

Comment exécuter une fonction en arrière-plan de tkinter

Je suis nouveau à la programmation de GUI et je veux écrire un programme Python avec Tkinter. Tout ce que je veux que ce soit soit exécuté une fonction simple dans l'arrière-plan qui peut être influencé par l'interface graphique.

La fonction compte de 0 à l'infini jusqu'à ce qu'un bouton soit enfoncé. Au moins c'est ce que je veux que ce soit. Mais je n'ai aucune idée de la façon dont je peux exécuter cette fonction en arrière-plan, car le Mainloop () de Tkinter a le contrôle tout le temps. Et si je démarre la fonction dans une boucle sans fin, le Mainloop () ne peut pas être exécuté et l'interface graphique est morte. P>

Je voudrais retourner le contrôle au Mainloop () après chaque cycle, mais comment peut-on Je reçois le contrôle du contrôle du Mainloop () à la fonction RunPApp sans événement déclenché par l'utilisateur? P>

Voici quelques échantillons de code qui tue l'interface graphique: P>

from Tkinter import *

class App:
    def __init__(self, master):

        frame = Frame(master)
        frame.pack()

        self.button = Button(frame, text="START", command=self.runapp)
        self.button.pack(side=LEFT)

        self.hi_there = Button(frame, text="RESTART", command=self.restart)
        self.hi_there.pack(side=LEFT)

        self.runapp()

    def restart(self):
        print "Now we are restarting..."

    def runapp(self):
        counter = 0
        while (1):
            counter =+ 1
            time.sleep(0.1)


0 commentaires

5 Réponses :


4
votes

Vous trouverez la réponse dans cette autre question Tkinter verrouille Python lorsque l'icône est chargée et tk.mainloop dans un fil .

En un mot, vous devez avoir deux threads, un pour Tkinter et un pour la tâche d'arrière-plan.


1 commentaires

Pour ce simple programme, il n'est absolument pas nécessaire d'utiliser des threads. C'est comme tuer une fourmi avec une tronçonneuse.



9
votes

La programmation basée sur les événements est conceptuellement simple. Imaginez simplement qu'à la fin de votre fichier de programme est une simple boucle infinie:

def add_one(self):
    self.counter += 1
    self.after(1000, self.add_one)


0 commentaires

2
votes

Je n'ai pas suffisamment de réputation pour commenter la réponse de Bryan Oakley (que j'ai trouvé très efficace dans mon programme), je vais donc ajouter mon expérience ici. J'ai découvert que, selon la durée de la longueur de votre fonction d'arrière-plan pour exécuter, et à quel point vous voulez que l'intervalle de temps soit précis, il peut être préférable de mettre auto.Après code> appel au début de la récurrence fonction. Dans l'exemple de Bryan, cela ressemblerait à

def add_one(self):
    self.after(1000, self.add_one)
    self.counter += 1


1 commentaires

Pour éviter la dérive, vous pouvez verrouiller le retard avec une minuterie. Comment exécuter une fonction périodiquement à Python



4
votes

Essayez de comprendre cet exemple: horloge mettant la mise à jour dans le backgroud et mettre à jour l'interface graphique (pas besoin de 2 threads). xxx

Crédits: Lien vers site


0 commentaires

0
votes

Si vous ne voulez pas être loin de ces discussions, je voudrais donner une suggestion pour votre guidon Placez la fonction pour votre interface graphique juste avant la déclaration root.mainloop ().

Exemple - P>

root = tk.Tk()
.
.
graphicsfunction()     #function for triggering the graphics or any other background 
                       #function
root.mainloop()


0 commentaires