如何重置PyQt singleShot定时器 无需新建实例重新计数
QTimer单次定时器重置实现方法
核心问题原因
直接调用QTimer.singleShot()静态方法生成的一次性定时器,无法直接对原有实例做重置操作。每次点击按钮新建定时器实例的写法存在隐患:旧定时器实例不会被销毁,到达超时时间后依然会触发回调,导致逻辑重复执行。
实现思路
不要使用静态singleShot()方法,复用同一个QTimer实例即可实现重置需求:
- 初始化定时器时,通过
setSingleShot(True)将实例配置为单次触发模式 - 绑定超时回调信号后,调用
start(间隔毫秒数)启动计时 - 需要重置时,直接对同一个实例再次调用
start(5000),定时器会自动终止当前计时、从0重新开始计数,不需要创建新实例 - 停止定时器时保持原有
stop()调用即可
修正后代码
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) # 配置为单次触发模式 self.timer.setSingleShot(True) # 绑定超时回调 self.timer.timeout.connect(self.shot) # 启动计时 self.timer.start(5000) 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.start(5000) 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())
补充说明:初始化QTimer时传入父对象
self可以将定时器绑定到窗口生命周期,窗口销毁时定时器会自动回收,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

