QtCore.QTimer间隔时间随启动次数递增问题求助
PyQt5计时器间隔异常变长问题的原因及解决
问题描述
我用PyQt5开发了带有「Start Timer」和「Stop Timer」按钮的界面,期望每次点击「Start Timer」时,QtCore.QTimer能以1秒间隔持续计时。但实际运行时,第一次启动间隔为1秒,第二次变为2秒,后续每次启动间隔还会持续变长,想知道该错误的原因。
代码实现
from PyQt5 import QtWidgets, QtGui, QtCore class CustomWidget(QtWidgets.QWidget): def __init__(self): super().__init__() self.layout = QtWidgets.QGridLayout() self.button1 = QtWidgets.QPushButton("Start Timer") self.button2 = QtWidgets.QPushButton("Stop Timer") self.label1 = QtWidgets.QLabel("") self.label1.setWordWrap(True) self.timer=QtCore.QTimer() self.layout.addWidget(self.button1, 0, 0) self.layout.addWidget(self.button2, 0, 1) self.layout.addWidget(self.label1, 1, 0, 1, 3) self.setLayout(self.layout) self.layout.setColumnStretch(2, 1) self.layout.setRowStretch(2, 1) self.button1.clicked.connect(self.start_timer) self.button2.clicked.connect(self.stop_timer) def start_timer(self): self.timer.timeout.connect(self.startPressed) self.timer.start(1000) self.timer.setInterval(1000) self.timecount=0 def startPressed(self): self.label1.setText(str(self.timecount)) self.timecount=self.timecount+1 def stop_timer(self): self.timer.stop() class App(QtWidgets.QWidget): def __init__(self): super().__init__() self.cw = CustomWidget() self.layout = QtWidgets.QVBoxLayout() self.layout.addWidget(self.cw) self.setLayout(self.layout) self.show() QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create("Fusion")) app = QtWidgets.QApplication([]) win = App() status = app.exec_()
错误原因
核心问题是每次点击「Start Timer」时,都会重复给timeout信号绑定同一个槽函数startPressed:
- 第一次点击启动,
timeout信号绑定1次startPressed,计时器每秒触发1次,槽函数执行1次,timecount每秒+1,间隔正常。 - 第二次点击启动,未断开之前的绑定,
timeout信号又新增1次绑定,此时计时器每秒触发时,槽函数会被执行2次,timecount每秒+2,视觉上表现为计时间隔“变长”(实际是数值跳变速度翻倍)。 - 后续每点击一次启动,绑定次数就增加一次,槽函数执行次数同步增多,最终间隔“变长”的现象会越来越明显。
解决方法
以下三种方式任选其一即可:
1. 仅在初始化时绑定一次信号槽
把timeout信号的连接逻辑移到__init__方法中,避免重复绑定:
def __init__(self): # ... 其他初始化代码 ... self.timer.timeout.connect(self.startPressed) # 移至初始化阶段 self.button1.clicked.connect(self.start_timer) self.button2.clicked.connect(self.stop_timer) def start_timer(self): self.timer.start(1000) self.timecount=0 # 移除重复的connect代码
2. 启动前先断开已有连接
在启动计时器前,先断开timeout与startPressed的连接,再重新绑定:
def start_timer(self): try: self.timer.timeout.disconnect(self.startPressed) except TypeError: pass # 未连接时会抛出TypeError,直接忽略 self.timer.timeout.connect(self.startPressed) self.timer.start(1000) self.timecount=0
3. 使用唯一连接标志
连接时添加QtCore.Qt.UniqueConnection标志,重复连接不会创建新的绑定:
def start_timer(self): self.timer.timeout.connect(self.startPressed, QtCore.Qt.UniqueConnection) self.timer.start(1000) self.timecount=0
内容的提问来源于stack exchange,提问作者Qian
相关产品推荐
相关产品推荐

