QThread是Qt线程类中最核心的底层类。使用QThread时,我们需要建立一个自定义的类,像下面的代码中我们建立了一个WorkThread类,使它继承于QThread
常用方法如下:
方法 | 描述 |
---|---|
start() | 启动线程 |
wait() | 阻止线程,直到满足如下条件之一:1. 与此QThread对象关联的线程完成执行,此函数将返回True;如果线程尚未启动,此函数也返回True。 2. 等待时间的单位是毫秒。如果时间是ULONG_MAX(默认值),则等待,永远不会超时;如果等待超时,则返回False |
started() | 开始执行run()之前,与相关线程发射此信号 |
finished() | 当程序完成任务时,发射此信号 |
sleep() | 强制线程休眠(单位:秒) |
下面代码举了一个例子:
import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
count = 0
# 工作线程
class WorkThread(QThread):
# pyqtSignal是信号类
timeout = pyqtSignal() # 每隔一秒发送一个信号
end = pyqtSignal() # 计数完成后发送一个信号
def run(self):
while True:
# 休眠1秒
self.sleep(1)
if count == 3:
self.end.emit() # 发送end信号,调用和end信号关联的方法
break
self.timeout.emit() # 发送timeout信号
class Counter(QWidget):
def __init__(self):
super(Counter, self).__init__()
self.setWindowTitle("用QThread编写计数器")
self.resize(300, 200)
layout = QVBoxLayout()
# QLCDNumber 用于模拟LED显示效果,类似于Label
self.lcdNumber = QLCDNumber()
layout.addWidget(self.lcdNumber)
button = QPushButton("开始计数")
layout.addWidget(button)
self.workThread = WorkThread()
self.workThread.timeout.connect(self.countTime)
self.workThread.end.connect(self.end)
button.clicked.connect(self.work)
self.setLayout(layout)
def countTime(self):
global count
count += 1
self.lcdNumber.display(count)
def end(self):
QMessageBox.information(self, '消息', '计数结束', QMessageBox.Ok)
def work(self):
self.workThread.start()
if __name__ == "__main__":
app = QApplication(sys.argv)
main = Counter()
main.show()
sys.exit(app.exec_())
代码分析:
1. 线程使用的一般形式:
QThread
def run(self):
while True:
self.sleep(1)
if sec == 5:
break;
2. 我们常常使用自定义的线程,例如在本案例中,我们创建了一个WorkThread线程,继承与QThread,它用到自定义信号,用于在两个对象之间交互
3. 在这个代码中,我们自定义了两个信号,注意的是,如果我们要自定义一个信号,必须要用pyqtSignal()这个方法来创建信号,并使用emit()发射信号,在后续代码中,我们要定义一个槽来分别接收这些信号。
class WorkThread(QThread):
# pyqtSignal是信号类
timeout = pyqtSignal() # 每隔一秒发送一个信号
end = pyqtSignal() # 计数完成后发送一个信号
def run(self):
while True:
# 休眠1秒
self.sleep(1)
if count == 3:
self.end.emit() # 发送end信号,调用和end信号关联的方法
break
self.timeout.emit() # 发送timeout信号
4. 在第三点中提到要定义一个槽来接收信号,下面就从代码中截取出连接信号与槽的代码
self.workThread.timeout.connect(self.countTime)
self.workThread.end.connect(self.end)
效果如图: