一般情况下,应用程序都是单线程运行的,但如果需要执行一个特别耗时的操作,GUI界面其他操作就无法进行,用户感觉程序没有了响应,或者windows系统也认为程序运行出现了问题并自动关闭了程序。有类似的情况应用就需要采用定时器和线程。
1 定时器(QTimer)
如果要在应用程序中周期性地运行某项操作,则可以使用QTimer定时器。
其常用的方法如下:
方法 | 描述 |
---|---|
start(n) | 启动或重启定时器,时间间隔为n毫秒。如果定时器已经允许,它将被停止并重新启动。如果singleShot信号为真,定时器仅被激活一次 |
stop() | 停止定时器 |
QTimer类常用的信号
信号 | 描述 |
---|---|
singleShot | 在给定的时间间隔后调用一个槽函数时发送次信号 |
timeout | 当定时器超时时发出此信号 |
要使用定时器,首先引入QTimer模块,创建一个QTimer实例,将其timeout信号连接到相应的槽函数,调用start(毫秒数)设定时间间隔后启动定时器,定时器会以指定的间隔发出timeout信号,执行槽函数。
# -*- coding:utf-8 -*-
"""
------------------------------------------------
File Name: 定时器.py
Description:
Author: lzq
date:2024-08-04 11:08
------------------------------------------------
"""
import sys
from PyQt6.QtCore import QTimer, QDateTime
from PyQt6.QtWidgets import QApplication, QWidget, QLabel
class MyWidget(QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
self.setWindowTitle("定时器QTimer测试")
self.resize(330,120)
self.label=QLabel('',self)
self.label.setGeometry(20,20,180,60)
self.timer=QTimer(self)
self.timer.timeout.connect(self.showTime)
self.timer.start(1000)
def showTime(self):
time=QDateTime.currentDateTime()
timeDisplay=time.toString("yyyy-MM-dd hh:mm:ss dddd")
self.label.setText(timeDisplay)
if __name__=='__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.show()
sys.exit(app.exec())
2 线程(QThread)
QThread时PyQt6线程类中最核心的底层类
(1)要使用QThread开始一个线程,可以创建它的一个子类(集成QThread),重载QThread.run方法。
class Thread(QThread):
def __init__(self):
super(Thread,self).__init__()
def run(self):
#线程代码
pass
(2)然后创建一个新的线程,启动线程:
thread=Thread()
thread.start()
线程启动后会自动调用其实现run方法,线程任务(例如读取数据显示在界面中)就写在run方法中,当run方法退出之后线程基本就结束了。
QThread类中的常用方法如下:
方法 | 描述 |
---|---|
start() | 启动线程 |
wait(n) | 阻止线程 |
sleep(n) | 强制当前线程睡眠n秒 |
msleep(n) | 当前线程睡眠n毫秒 |
quit() | 退出线程事件并返回0(成功),相当于exit():0。 |
exit() | 退出线程事件循环并返回代码。返回0表示成功,非0表示错误 |
terminate() | 强制终止线程 |
setPriority(枚举) | 设置线程优先级 |
isFnished() | 线程是否完成 |
isRunning() | 线程是否正在运行 |
QThread常用的信号如下:
started:在开始执行run之前,从相关线程发送此信号。
finished:当程序完成业务逻辑时,从相关线程发送此信号。
可为这两个信号指定槽函数,在线程启动和结束时进行资源的初始化和释放操作。或者在自定义的QThread实例中自定义信号,并将信号连接到指定的槽函数,当满足指定条件后发送此信号。
from PyQt6.QtCore import QThread, pyqtSignal, QDateTime
class Worker(QThread):
strOutSignal=pyqtSignal(str)
def __init__(self,parent=None):
super(Worker,self).__init__(parent)
self.working=True
def run(self):
while self.working ==True:
time=QDateTime.currentDateTime()
timeStr=time.toString("yyyy-MM-dd hh:mm:ss dddd")
self.strOutSignal.emit(timeStr)
self.sleep(1)
通过pyqt ui实现页面操作及显示:
import sys
from PyQt6.QtWidgets import QPushButton, QApplication, QWidget, QListWidget, QGridLayout
class MyWidget(QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
self.setWindowTitle("QThread线程测试")
self.resize(330,120)
self.listStr=QListWidget()
self.pdStart=QPushButton('开始')
layout=QGridLayout(self)
layout.addWidget(self.listStr,0,0,1,2)
layout.addWidget(self.pdStart,1,1)
self.pdStart.clicked.connect(self.threadStart)
self.thread=Worker()
self.thread.strOutSignal.connect(self.listStrAdd)
def listStrAdd(self, strInf):
self.listStr.addItem(strInf)
def threadStart(self):
self.pdStart.setEnabled(False)
self.thread.start()
if __name__=='__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.show()
sys.exit(app.exec())