Logik von withdraw()

Fragen zu Tkinter.
Antworten
Janux
User
Beiträge: 78
Registriert: Donnerstag 12. Juni 2008, 21:11

Hallo!
Ich möchte mein Pausenprogramm jetzt dahingehend erweitern, dass
nach 2h 15min Pause gemacht wird. Die Werte die momentan im code
stehen sind nur zum Testen.

Mein Problem ist folgendes: Anstatt wie erwartet zuest eine Sekunde ein
grauer Bildschirm und danach immer 5sec grau welchselt sich eine
Sekunde und 5sec jedes mal ab.

Warum wird self.zaehler jedes mal auf 0 zurück gesetzt?

Code: Alles auswählen

import Tkinter as tk
import winsound as ws
import os

class App():
    zaehler = 0
    
    def __init__(self):
        self.root = tk.Tk()
        self.arbeitszeit = 25   # Arbeitszeit in Minuten
        self.root.overrideredirect(1)
        w, h = self.root.winfo_screenwidth(), self.root.winfo_screenheight()
        self.root.geometry("%dx%d+0+0" % (w, h))
        self.root.focus_set()

        self.arbeiten()

        self.root.mainloop()
        
    def manager(self):
        if self.zaehler == 0:
            self.zaehler += 1
            self.pause(1)
        if self.zaehler == 1:
            self.pause(5)
 
    def arbeiten(self):
        self.root.withdraw()
        ws.Beep(5000,5)
        self.root.after(1000, self.manager)
        
    def pause(self, pausenzeit):
        self.root.deiconify()
        self.root.after(1000*pausenzeit, self.arbeiten) 

a =App()
edit: Außerdem sind es noch nicht einmal 5sec sondern nur drei.
Woran kann das liegen?
mfg ... Janux
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Indirekt liegt es auf jeden Fall daran, dass dein Code zu verworren ist:
arbeiten() ruft manager() auf, manager() ruft pause() auf und pause() ruft wiederum arbeiten() auf. Das ist nicht gut.

Was genau willst du denn erreichen? Warum erst 1 Sekunde, dann (wann?) 5 Sekunden? Beschreib mal genau, welches zeitliche Verhalten dein Pausenerinnerer an den Tag legen soll.
Janux
User
Beiträge: 78
Registriert: Donnerstag 12. Juni 2008, 21:11

Code: Alles auswählen

    def arbeiten(self):
        self.root.withdraw()

        if self.zaehler == 0:
            self.zaehler += 1
            self.root.after(1000, self.pause, 1)
        if self.zaehler == 1:
            self.root.after(1000, self.pause, 5)
So gibt es aber auch die gleichen Effekte.

Am Ende soll das Programm folgendermaßen laufen:

def "Arbeit&Pause"
{
25 min arbeiten
5 min Pause
}

2 * Arbeit&Pause
15 min Pause
2 * Arbeit&Pause
--> PC herrunterfahren
1-2 h Pause


Der code des Modell war so geplant:
1 sec Arbeit
1 sec Pause
1 sec Arbeit
5 sec Pause
1 sec Arbeit
5 sec Pause
1 sec Arbeit
5 sec Pause

usw...

Jetzt läuft er aber so:
1 sec Arbeit
1 sec Pause
1 sec Arbeit
3 sec Pause
1 sec Arbeit
1 sec Pause
1 sec Arbeit
3 sec Pause

usw...
mfg ... Janux
BlackJack

@Janux: Bevor Du behauptest das `zaehler` auf 0 gesetzt wird, schau doch erst einmal nach ob das *wirklich* der Fall ist. Und mit `withdraw()` hat das auch nichts zu tun.

Du startest damit, dass in `arbeiten()` nach einer Sekunde `manager()` aufgerufen wird.

In Manager wird `pause(1)` aufgerufen, das heisst in jetzt+1 Sekunde wird `arbeiten()` aufgerufen. Und *gleich danach* rufst Du `pause(5)` auf! Denn `self.zähler` ist ja jetzt 1 nachdem Du ihn in dem ``if``-Zweig davor erhöht hast! Situation: in einer Sekunde wird `arbeiten()` aufgerufen und in fünf Sekunden noch einmal.

Eine Sekunde später wird also `arbeite()` aufgerufen. Immer im Hinterkopf behalten, dass es in vier Sekunden noch einmal aufgerufen wird! Arbeite sagt, das in einer Sekunde `manager()` aufgerufen werden soll. Ereignisse also: in einer Sekunde `manager()` und in vier Sekunden `arbeite()`.

Eine Sekunde später wird `manager()` aufgerufen, sagt, dass in fünf Sekunden `arbeite` aufgerufen werden soll. Jetzt haben wir also in drei Sekunden *und* in fünf Sekunden den Aufruf für `arbeite()` in der Warteschlange. Und nach drei Sekunden ist die Pause deshalb schon wieder um. Und so weiter…
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

@Janux:
Wenn ich es richtig verstehe, dann soll dein Pausenprogramm auch nichts weiter machen, als zu bestimmten Zeiten auf Pausen hinzuweisen.
Wenn das so stimmt, dann gibt es eigentlich keinen Grund, ereignisgesteuert zu arbeiten und die after()-Methode zu bemühen.

Mach es doch ganz einfach so (als Grundidee - den grauen Bildschirm hast du ja schon hinbekommen):

Code: Alles auswählen

from time import sleep

arbeitszeit = 1
pausenzeit = 1
while True:
    print "Arbeit"
    sleep(arbeitszeit)
    print "Pause"
    sleep(pausenzeit)
    pausenzeit = 5
Janux
User
Beiträge: 78
Registriert: Donnerstag 12. Juni 2008, 21:11

@ BlackJack: elif ist schon eine schöne Erfindung. Ich mach jetzt erstmal Pause :lol: Danke!

@ Numerix: Jetzt funktioniert es genau wie ich es haben möchte. Danke für deine Bemühungen!
mfg ... Janux
Antworten