Countdown immer größere Schritte

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
melectric
User
Beiträge: 3
Registriert: Sonntag 17. Mai 2020, 20:47

Hallo zusammen,

ich bastele im Moment an einem Countdown Programm. Die Zeitanzeige steuere ich mit ein Start-Button und einem Pause-Button der den Timer stoppt.

Das ganze funktioniert auf den ersten Blick auch. Allerdings wenn ich den Timer stoppe und wieder auf Start drücke zählt er dann 2 Sekunden pro "tick" runter. Und mit jedem mal Stopp&Start wird es eine Sekunde mehr. Also nach 9 mal stoppen und wieder starten gehen pro Sekunde 10 Sekunden von der Uhr weg.

Ich hoffe jemand kann mir hier weiterhelfen.

Vielen Dank im Voraus.

Code: Alles auswählen

from PyQt5 import QtWidgets, QtCore, QtGui
import StortiTimer
from datetime import time, timedelta, datetime

class ControlLCD(QtWidgets.QWidget):
    def __init__(self, parent = None):
        QtWidgets.QWidget.__init__(self, parent)
        self.ui = StortiTimer.Ui_set_time()
        self.ui.setupUi(self)   
        self.timer = QtCore.QTimer(self)
        #working variables
        self.job_time = None
        self.first_time = None
        self.timey = timedelta(seconds = 1)
        self.ostime = datetime(year= 2030, month = 1, day=1, hour=0, minute=0, second=0)
        
        #connect buttons to events
        self.ui.start_button.clicked.connect(self.start_timer)
        self.ui.kill_Button.clicked.connect(self.quit)
        self.ui.pause_button.clicked.connect(self.pause)
        self.ui.set_button.clicked.connect(self.set_time)


        
    
    def updateLCD(self):
        if self.first_time.hour != 0 or self.first_time.minute != 0 or self.first_time.second != 0:
            self.first_time -= self.timey
            printstring = f"{self.first_time.hour}:{self.first_time.minute}:{self.first_time.second}"
            self.ui.remaining_time.setText(printstring)
            self.timey = timedelta(seconds = 1)
        else:
            self.overshoot()

    def overshoot(self):
        self.ostime += self.timey
        printos = f"{self.ostime.hour}:{self.ostime.minute}:{self.ostime.second}"
        self.ui.extra_time.setText(printos)



        
    
    def set_time(self):
        ''' Get the time from the time setting Window and paste it to the clock'''
        self.job_time = self.ui.job_time.time()
        print_init_time = self.job_time.toString("hh:mm:ss")
        self.ui.remaining_time.setText(print_init_time)
        self.first_time = datetime(year = 2030, month = 1, day = 1, hour= self.job_time.hour(), minute=self.job_time.minute(), second= self.job_time.second())
        


    def start_timer(self):
        self.timey = timedelta(seconds = 1)
        self.timer.start(1000)
        #set the timer event
        self.timer.timeout.connect(self.updateLCD)
    
    def pause(self):
        self.timer.stop()
        self.timey = timedelta(seconds = 1)

    
    def quit(self):
        sys.exit()
        

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    c = ControlLCD()
    c.show()
    sys.exit(app.exec_())
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ein Klassiker. Nur weil du dem OS sagst “warte 1 Sekunde” wartet das nicht exakt eine Sekunde. Das wird immer ein bisschen, und gelegentlich deutlich später zurück kehren. Und darum merkst du dir die Startzeit mittels time.monotonic(), und misst die tatsächlich verflossene Zeit dann mit time.monotonic() - start.
Benutzeravatar
__blackjack__
User
Beiträge: 14005
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das ist auch ein Problem, aber trotzdem sollte man nicht bei jedem (neu)start das Signal noch ein weiteres mal mit dem Slot verbinden, denn dann wird das ja auch jedes mal einmal mehr pro Sekunde aufgerufen.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
melectric
User
Beiträge: 3
Registriert: Sonntag 17. Mai 2020, 20:47

__blackjack__ hat geschrieben: Sonntag 17. Mai 2020, 21:04 Das ist auch ein Problem, aber trotzdem sollte man nicht bei jedem (neu)start das Signal noch ein weiteres mal mit dem Slot verbinden, denn dann wird das ja auch jedes mal einmal mehr pro Sekunde aufgerufen.
Wärst du so gut mir zu erklären was du damit meinst? Wo findet diese erneute Verbindung in meinem Code statt?
Bin leider recht neu bei Python und kann dir nicht folgen.
Benutzeravatar
__blackjack__
User
Beiträge: 14005
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@melectric: Verbinden heisst auf Englisch `connect`. Welcher Code wird denn jedes mal ausgeführt wenn der Startknopf gedrück wird? Und was passiert dort dann jedes mal?
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
melectric
User
Beiträge: 3
Registriert: Sonntag 17. Mai 2020, 20:47

__blackjack__ hat geschrieben: Sonntag 17. Mai 2020, 21:16 @melectric: Verbinden heisst auf Englisch `connect`. Welcher Code wird denn jedes mal ausgeführt wenn der Startknopf gedrück wird? Und was passiert dort dann jedes mal?
Gehe ich recht in der Annahme, dass es

Code: Alles auswählen

self.timer.timeout.connect(self.updateLCD)
ist?
Diese Zeile darf dann nur beim ersten mal Start ausgeführt werden?

habe das ganze jetzt wie folgt gelöst:

Code: Alles auswählen

def start_timer(self):
        self.timey = timedelta(seconds = 1)
        self.timer.start(1000)
        #set the timer event
        if self.first_start == True:
            self.timer.timeout.connect(self.updateLCD)
            self.first_start = False
jetzt tut es wie es soll vielen Dank
Benutzeravatar
__blackjack__
User
Beiträge: 14005
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@melectric: Warum? Alle anderen Verbindungen machst Du doch auch *ein mal* in der `__init__()`.

Und die Anmerkung von __deets__ gilt natürlich auch weiterhin: das ist ungenau und die Ungenauigkeiten summieren sich über die Zeit.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Antworten