Je travaille sur la création d'un chronomètre qui a deux valeurs. Il commence par la valeur A et compte à rebours jusqu'à 0, puis passe à la valeur B, compte à rebours jusqu'à 0, puis revient à la valeur A, compte à rebours jusqu'à 0, etc. jusqu'à ce que je ferme le programme (j'ajouterai probablement un bouton de pause à certains point) et dans l'ensemble ça marche vraiment bien. Cependant, lorsqu'il met à jour l'étiquette avec le nouveau texte, il semble simplement créer un nouvel élément de texte et le mettre en tant que calque au-dessus du précédent. Je peux voir alors quand je passe d'un numéro à deux chiffres à un seul chiffre et que la phrase est raccourcie, la partie de l'ancienne phrase qui n'est pas couverte peut encore être vue. J'espère donc qu'il me manque quelque chose d'incroyablement simple. Le newWindow.update() est ce que je pensais mettre à jour la fenêtre mais il ne semble pas le faire. Voici mon extrait de code qui gère la logique.

    def countdown(timer_count,count_type):
        counter = timer_count
        count_type = count_type
        while counter >= 0:
            timer = tk.Label(newWindow, text=f"{count_type} for: {counter}")
            timer.config(font=("TkDefaultFont",30))
            timer.grid(row=0,column=2)
            newWindow.update()
            time.sleep(1)
            counter -= 1
            print(counter)
        if count_type == "work":
            count_type = "rest"
        elif count_type == "rest":
            count_type = "work"
        return count_type


    def interval():
        counter_type = "work"
        while True:
            if counter_type == "work":
                counter_type = countdown(int(exer_var.get()),counter_type)
            elif counter_type == "rest":
                counter_type = countdown(int(rest_var.get()),counter_type)
0
jon 25 févr. 2021 à 00:32

2 réponses

Meilleure réponse

Vous créez un nouveau widget Label à chaque fois dans votre boucle while au lieu de changer le texte à l'intérieur de la boucle while. C'est pourquoi il superpose un widget au dessus de l'autre, vous devez donc créer votre widget, puis exécuter la boucle while et définir le texte pour qu'il change dans le timer.config à l'intérieur de la boucle. Vous devez également déclarer la police dans l'original tk.Label, pas besoin de changer cela à chaque voyage dans la boucle. Pour "some_starting value", ce serait probablement "text = counter"

timer = tk.Label(newWindow, font=("TkDefaultFont",30), text="some_starting_value")
    while counter >= 0:
        timer.config(text=f"{count_type} for: {counter}")
        timer.grid(row=0,column=2)
1
skytale 24 févr. 2021 à 22:02

Il est difficile de dire à partir de votre code où cela se passe, mais voici comment cela se fait habituellement:

  • Créez l'étiquette en dehors de toutes les fonctions du bloc principal.
timer = tk.Label(newWindow,font=("TkDefaultFont",30)) # Adding the font here itself
  • Ensuite, à l'intérieur de la fonction, changez simplement sa valeur en utilisant config:
def countdown(timer_count,count_type):
    counter = timer_count
    count_type = count_type
    while counter >= 0:
        timer.config(text=f"{count_type} for: {counter}") # Update the options for the created label.
        timer.grid(row=0,column=2)

Alors maintenant, chaque fois que la fonction / boucle est en cours d'exécution, de nouvelles étiquettes ne seront pas créées et écrasées, à la place l'étiquette existante sera configurée.


Par ailleurs, l'utilisation de la boucle time.sleep() et while n'est pas la meilleure pratique, même avec update(), cela causera toujours une sorte de perturbation de l'interface graphique. Au lieu de cela, réorganisez votre code pour utiliser la méthode after(ms,func), qui ne gèlera pas l'interface graphique. Vous pouvez poser une nouvelle question à ce sujet si vous rencontrez des problèmes, plus tard.

1
Cool Cloud 24 févr. 2021 à 22:03