QTimer的作用有两个:一个是执行周期性任务,另一个是执行一次性定时任务。定时器往往同QThread配合使用。
一、执行周期性任务
使用定时器执行周期性任务分为4个步骤
python
1.创建QTimer对象,一定要将QTimer赋值给对象属性
self.timer=QTimer()
2.信号timeout
self.timer.timeout.connect(self.showTime)
3.启动定时器的方法,设置启动定时器的间隔时间,单位:毫秒
self.timer.start(1000)
4.停止定时器的方法
self.timer.stop()
示例代码
python
import sys
from PyQt5.QtCore import QDateTime, QTimer
from PyQt5.QtWidgets import *
class MyWin(QWidget):
def __init__(self):
super().__init__()
self.setUI()
def setUI(self):
self.timeLabel=QLabel("显示当前时间")
self.startButton=QPushButton("开始")
self.endButton=QPushButton("结束")
lay=QGridLayout()
lay.addWidget(self.timeLabel,0,0,1,2)
lay.addWidget(self.startButton,1,0)
lay.addWidget(self.endButton,1,1)
self.setLayout(lay)
self.timer=QTimer()
self.timer.timeout.connect(self.showTime)
self.startButton.clicked.connect(self.startTimer)
self.endButton.clicked.connect(self.stopTimer)
def showTime(self):
time=QDateTime.currentDateTime()
timeDisplay=time.toString("yyyy-MM-dd hh:mm:ss dddd")
self.timeLabel.setText(timeDisplay)
def startTimer(self):
self.timer.start(1000) # 设置定时器的间隔时间,单位:毫秒
def stopTimer(self):
self.timer.stop()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWin()
w.show()
app.exec()
二、执行一次性定时任务
使用定时器的静态方法singleShot方法实现。
属于QTimer的静态方法,直接通过QTimer.singleShot()调用,无需实例化QTimer类(也可通过实例调用,但无意义)。
python
QTimer.singleShot(msec, callback)
msec int 延迟时间,单位为毫秒(ms),如1000表示延迟 1 秒执行。
callback 函数/方法 延迟后要执行的可调用对象(函数、类方法、lambda 表达式等)
示例代码
python
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
if __name__=="__main__":
app=QApplication(sys.argv)
button=QPushButton("5秒后关闭窗口")
button.setWindowFlag(Qt.FramelessWindowHint)
button.show()
QTimer.singleShot(5000,app.quit)
app.exec()
另外还有一个方法setSingleShot,用于在创建实例对象时,使用timeout信号执行一次性定时任务。
示例代码
python
import sys
from PyQt5.QtCore import QTimer
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget
class ExampleWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("QTimer单次执行示例")
self.setGeometry(300, 300, 300, 200)
# 创建中央部件和布局
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout(central_widget)
# 创建标签显示状态
self.status_label = QLabel("定时器将在2秒后触发一次...")
layout.addWidget(self.status_label)
# 设置单次定时器
self.setup_single_shot_timer()
def setup_single_shot_timer(self):
# 创建QTimer对象
self.timer = QTimer(self)
# 设置为单次执行模式
self.timer.setSingleShot(True)
# 设置定时器间隔为2000毫秒(2秒)
self.timer.setInterval(2000)
# 连接timeout信号到槽函数
self.timer.timeout.connect(self.on_timer_timeout)
# 启动定时器
self.timer.start()
# 检查是否为单次模式
print(f"定时器是否为单次模式: {self.timer.isSingleShot()}")
def on_timer_timeout(self):
# 这个函数只会在2秒后执行一次
self.status_label.setText("定时器已触发!任务执行完成。")
print("单次定时任务执行完成!")
# 检查定时器是否还在运行
print(f"定时器是否仍在运行: {self.timer.isActive()}")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = ExampleWindow()
window.show()
sys.exit(app.exec_())
三、线程安全
singleShot触发的操作始终在主线程 执行,因此可以安全地操作 UI 控件;若需要在子线程中使用singleShot,需确保回调函数不直接操作 UI(仍需通过信号槽让主线程处理 UI)。这句话同样适用于QTimer的timeout信号。
四、其他方法
python
isSingleShot() 定时器是否为单次模式
isActive() 定时器是否在运行
setInterval()设置定时器间隔,单位为毫秒。
setInterval和start方法的区别,start方法,可以设置时间间隔参数也可以不设置。如果前面使用setInterval设置了时间间隔,则可以使用不带参数的start方法;如果使用带参数的start方法,则相当于使用了setInterval设置了时间间隔并使用不带参数的start方法。