9
votes

Comment puis-je arrêter Tkinter après la fonction?

J'ai un problème d'arrêt du "flux"; L'argument d'annulation ne semble avoir aucun impact sur la méthode après. Bien que le "flux arrêté" soit imprimé sur la console.

Je tente d'avoir un bouton qui démarrera l'alimentation et un autre qui arrêtera le flux. xxx

avec la sortie: xxx


3 commentaires

Je ne suis pas tout à fait sûr de la façon dont Tkinter fonctionne, mais cela ressemble à un problème de filetage pour moi. Si vous utilisez Annuler un (thread Safe) Global, cela résoudra-t-il le problème?


@mklauber: Non, pas un problème de threading. Tkinter est à filetage unique.


@Bryanoakley: merci. C'est pourquoi j'ai posté comme un commentaire. Je n'étais pas sûr que je voulais juste poser la question.


3 Réponses :


21
votes

Lorsque vous appelez root.after (...) , il retournera un identifiant. Vous devriez garder une trace de cet identifiant (par exemple, stockez-le dans une variable d'instance), puis vous pouvez appeler ultérieurement root.after_cancel (After_id) pour l'annuler.


1 commentaires

Comment obtenir l'identifiant?



25
votes

Le problème est que, même si vous appelez print_sleep avec true pour arrêter le cycle, il y a déjà un travail en attente d'incendie. En appuyant sur le bouton d'arrêt ne provoquera pas un nouvel emploi à tirer, mais l'ancien travail est toujours là, et quand il s'appelle elle-même, elle passe en faux qui provoque la poursuite de la boucle.

Vous devez annuler le travail en attente de sorte que Cela ne fonctionne pas. Par exemple: xxx

Remarque: assurez-vous d'initialiser self._job quelque part, par exemple dans le constructeur de votre objet d'application.


2 commentaires

Je dois faire cela, mais j'ai besoin de plus en détail - pourriez-vous fournir un exemple complet, y compris comment "initialiser self._job quelque part, comme dans le constructeur de votre objet d'application".


Comment obtenir l'identifiant de root.après () ? Appeler root.after_cancel ()



0
votes

Voici ma réponse avec seulement 3 lignes de code ajoutées. La réponse réside dans l'utilisation de .after_cancel (x) code> qui en mots simples, signifie que "arrêtez de faire" x "travail" fort>. Je crois en la lisibilité du code, donc je n'ai apporté que des modifications minimales à votre code qui a fait le travail. Jetez un coup d'oeil s'il vous plait. Merci.

from tkinter import Tk, Button
import random

keep_feeding = None


def goodbye_world():
    print("Stopping Feed")
    button.configure(text="Start Feed", command=hello_world)
    print_sleep(True)


def hello_world():
    print("Starting Feed")
    button.configure(text="Stop Feed", command=goodbye_world)
    print_sleep()


def print_sleep(cancel=False):
    global keep_feeding
    if not cancel:
        foo = random.randint(1000, 2500)
        print(f"Sleeping {foo}")
        keep_feeding = root.after(foo, print_sleep)
    else:
        root.after_cancel(keep_feeding)
        print("Feed Stopped")


root = Tk()
button = Button(root, text="Start Feed", command=hello_world)

button.pack()

root.mainloop()


0 commentaires