定时器
- QObject类(包括其子类)通过
startTimer()
方法开启一个定时器,并返回这个定时器的ID - 定时器开启之后,就会每隔指定时间(毫秒)执行一次该对象的timerEvent()方法
- 开启定时器的对象也可以通过
killTimer(timer_id)
方法来结束指定的定时器
-
API讲解
startTimer(ms, Qt.TimerType) # 开启一个定时器,并返回这个定时器的ID
参数说明:
ms:设置时间间隔,单位是毫秒。每隔指定时间间隔就调用一次timerEvent()方法
Qt.TimerType:设置定时器的类型
Qt.PreciseTimer:精确定时器:尽可能保持毫秒准确
Qt.CoarseTime:粗定时器:5%的误差间隔
Qt.VeryCoarseTimer:很粗的定时器:只能到秒级killTimer(timer_id) # 根据定时器ID,杀死定时器 timerEvent() # 定时器执行事件
-
应用场景
- 轮询
- 倒计时
- ......
-
案例1:制作一个倒计时器
-
要求:
- 创建一个窗口, 并设置一个子控件QLabel,展示10s倒计时
- 倒计时结束, 就停止计时
-
代码
from PyQt5.Qt import *
import sysclass MyLabel(QLabel): def timerEvent(self, a0: 'QTimerEvent') -> None: initial_ms = int(self.text()) initial_ms -= 1 if initial_ms >= 0: self.setText(str(initial_ms)) app = QApplication(sys.argv) w = QWidget() w.setWindowTitle('QObject定时器') w.resize(600, 600) laber = MyLabel(w) laber.resize(w.width(), w.height()) laber.setText("10") laber.setStyleSheet("font-size:180px; color:red;") laber.setAlignment(Qt.AlignCenter) laber.startTimer(1000) w.show() sys.exit(app.exec_())
-
代码运行之后能够满足案例要求。但是,我们从代码中可以看出来,程序倒计时到0之后,这个定时任务并没有结束,仅仅只是不再重新设置标签的值了
-
那么,我们要结束这个定时器,该怎么办呢?通过killTimer(timer_id)方法,那么关键是该如何获取到timer_id呢?
-
我们在MyLabel类里面再定义一个方法mystartTimer(),在这个方法里面再调用startTimer()方法,返回值设置给self.timer_id属性,此时在MyLabel类里面就都可以用到self.timer_id这个属性了
from PyQt5.Qt import *
import sysclass MyLabel(QLabel): def timerEvent(self, a0: 'QTimerEvent') -> None: initial_ms = int(self.text()) initial_ms -= 1 self.setText(str(initial_ms)) if initial_ms == 0: self.killTimer(self.timer_id) def mystartTimer(self, ms): self.timer_id = super().startTimer(ms) app = QApplication(sys.argv) w = QWidget() w.setWindowTitle('QObject定时器') w.resize(600, 600) laber = MyLabel(w) laber.resize(w.width(), w.height()) laber.setText("10") laber.setStyleSheet("font-size:180px; color:red;") laber.setAlignment(Qt.AlignCenter) laber.mystartTimer(1000) w.show() sys.exit(app.exec_())
-
再次运行代码,可以看到能够满足案例要求。而且在倒计时到0,这个计时器也被结束了
-
案例2:创建一个窗口, 通过定时器不断增加该窗口的尺寸大小
-
要求:
- 每100ms 宽高均增加10px
- 当宽度和高度为原来的2倍时,停止增加
from PyQt5.Qt import * import sys class MyWidget(QWidget): def __init__(self): super().__init__() self.setWindowTitle('QObject定时器') self.resize(200, 200) self.w = self.width() self.h = self.height() def timerEvent(self, a0: 'QTimerEvent') -> None: self.resize(self.width() + 10, self.height() + 10) if self.width() == 2 * self.w and self.height() == 2 * self.h: print(f'{self.width()}__{self.height()}') self.killTimer(self.timer_id) def mystartTimer(self,ms): self.timer_id = self.startTimer(ms) app = QApplication(sys.argv) w = MyWidget() print(f'{w.width()}__{w.height()}') w.mystartTimer(100) w.show() sys.exit(app.exec_())