pythonpyqt5qtimer

Reset or reinitialize a PyQt singleShot Timer to prevent function call


Is there a wy to reset a singleshot Timer? I set the singleShot timer to 5000ms and want to reset the timer by clicking a button so the timer starts again to count.

from PyQt5 import QtCore 
from PyQt5.QtCore import QTimer 
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QFrame, QLabel, QWidget 
import sys

class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.centralWidget = QWidget()
        self.mainLayout = QHBoxLayout()
        self.centralWidget.setLayout(self.mainLayout)
        self.setCentralWidget(self.centralWidget)
        self.mainFrame = QFrame(self.centralWidget)
        self.mainFrame.setContentsMargins(0,0,0,0)
        self.mainLayout.addWidget(self.mainFrame)
        self.vLay = QVBoxLayout(self.mainFrame)
        self.button = QPushButton()
        self.button.setText('press me')
        self.button2 = QPushButton()
        self.button2.setText('Stop')
        self.label = QLabel(self.mainFrame)
        self.label.setText('testLabel')
        self.vLay.addWidget(self.button)
        self.vLay.addWidget(self.button2)
        self.vLay.addWidget(self.label)
        self.timer = QTimer()
        self.timer.singleShot(5000, self.shot)
        self.label.setText('running')

        self.button.clicked.connect(self.resetTimer)
        self.button2.clicked.connect(self.stopTimer)

    def resetTimer(self):
        self.label.setText('reseted')
        self.timer = QTimer()
        self.timer.singleShot(5000, self.shot) 
    
    def stopTimer(self):
        self.timer.stop()
        self.label.setText('stopped')

    def shot(self):
        self.label.setText('shot')



if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

If i press the resetButton it seems that a new Timer would initialize but i want to reset the current timer.


Solution

  • The QTimer.singleShot() is a static function that creates a new single shot timer.

    You are not actually using the QTimer instance you've created, in fact you create a new timer every time you call that function.

    You have to set the singleShot property on the QTimer instance, connect it to the required slot, and start that timer:

    class MainWindow(QMainWindow):
        def __init__(self):
            # ...
            self.timer = QTimer()
            self.timer.setSingleShot(True)
            self.timer.setInterval(5000)
            self.timer.timeout.connect(self.shot)
            self.timer.start()
    
        def resetTimer(self):
            if self.timer.isActive():
                self.label.setText('reset')
            else:
                self.label.setText('restarted')
            # start() will always restart the timer, no matter if it was active
            # or not, and will use the previously set interval (set with 
            # setInterval() or the last start() call
            self.timer.start()
    

    An alternative and shorter syntax:

            self.timer = QTimer(singleShot=True, timeout=self.shot)
            self.timer.start(5000)