下面是详细的攻略。
在PyQt5中,线程类QThread被用来处理一些耗时的操作,以避免把这些操作放在主线程中引起其卡顿或者假死。下面我们详细讲解QThread的使用方法。
import sys
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QProgressBar
需要继承QThread,并添加需要执行的方法,使用pyqtSignal
来发射信号。
class MyThread(QThread):
# 自定义信号,代表运算完毕后传递的参数类型为int
result = pyqtSignal(int)
def __init__(self, parent=None):
super().__init__(parent)
def run(self):
# 这里面是需要执行的代码,可以新开一个线程去执行
for i in range(101):
self.result.emit(i)
self.msleep(100) # 线程休眠0.1s
创建一个窗口类,添加需要的控件。
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
# 添加按钮和进度条
self.btn_start = QPushButton('Start', self)
self.btn_start.setGeometry(10, 10, 60, 30)
self.progress_bar = QProgressBar(self)
self.progress_bar.setGeometry(80, 10, 200, 30)
创建槽函数,即当接收到信号时执行的函数。通过如下代码来连接自定义信号和槽函数:
self.thread = MyThread(self)
self.thread.result.connect(self.step)
实现槽函数代码,在其中更新进度条。
def step(self, val):
self.progress_bar.setValue(val)
点击按钮,启动线程,执行自定义线程类的代码。
def start_thread(self):
self.thread.start()
到此,使用QThread来实现多线程的基本过程就完成了,下面可以看两个示例:
这里我们在自定义线程类中使用了while循环,开启线程后便会不断运行。每次运行都会发射一个信号,用于更新窗口中的进度条。
import sys
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QProgressBar
class MyThread(QThread):
result = pyqtSignal(int)
def __init__(self, parent=None):
super().__init__(parent)
def run(self):
i = 0
while True:
i = i + 1 if i < 100 else 1
self.result.emit(i)
self.msleep(100)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.btn_start = QPushButton('Start', self)
self.btn_start.setGeometry(10, 10, 60, 30)
self.progress_bar = QProgressBar(self)
self.progress_bar.setGeometry(80, 10, 200, 30)
self.thread = MyThread(self)
self.thread.result.connect(self.step)
self.btn_start.clicked.connect(self.start_thread)
def step(self, val):
self.progress_bar.setValue(val)
def start_thread(self):
self.thread.start()
app = QApplication(sys.argv)
main_win = MainWindow()
main_win.show()
app.exec_()
这里我们在线程类中创建一个参数,启动线程时传入,线程运行时使用该参数执行操作,并将操作结果作为信号传递给窗口类中的槽函数更新进度条。
import sys
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QProgressBar
class MyThread(QThread):
result = pyqtSignal(int)
def __init__(self, parent=None):
super().__init__(parent)
self._loop_cnt = 0
def set_cnt(self, cnt):
self._loop_cnt = cnt
def run(self):
for i in range(1, self._loop_cnt+1):
self.result.emit(i)
self.msleep(100)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.btn_start = QPushButton('Start', self)
self.btn_start.setGeometry(10, 10, 60, 30)
self.progress_bar = QProgressBar(self)
self.progress_bar.setGeometry(80, 10, 200, 30)
self.thread = MyThread(self)
self.thread.result.connect(self.step)
self.btn_start.clicked.connect(self.start_thread)
def step(self, val):
self.progress_bar.setValue(val)
def start_thread(self):
self.thread.set_cnt(100)
self.thread.start()
app = QApplication(sys.argv)
main_win = MainWindow()
main_win.show()
app.exec_()
这两个示例都是非常实用的,希望对大家有所帮助。