PySide6之多线程
一、QThread
方法1:子类化创建多线程
- 创建子线程,继承自QThread类
- 在子线程中自定义信号
- 在子线程中重写 run() 方法,进行信号的触发
- 在主线程中实例化子线程
- 在主线程中对子线程的信号进行绑定
- 在主线程中开启子线程
import time
from PySide6.QtCore import *
from PySide6.QtWidgets import *
# s1. 子线程类:继承自QThread
class WorkThread(QThread):
# s2. 自定义信号
signal = Signal(str)
def __init__(self):
super().__init__()
# 重写 run() 方法
def run(self):
for i in range(10):
time.sleep(1)
# s3. 信号触发
self.signal.emit(str(i)) # 发送信号
# 主线程
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# 创建一个标签,用于显示子线程的信号
self.label = QLabel()
# s4. 实例化子线程
self.workThread = WorkThread() # 用self实例化,防止子线程被回收
# s5. 对子线程的信号进行绑定
self.workThread.signal.connect(lambda x: self.label.setText(f"当前的值为:{x}")) # 将信号连接到标签
self.workThread.started.connect(lambda: self.label.setText("子线程开启")) # 子线程开启时激活
self.workThread.finished.connect(lambda: self.label.setText("子线程关闭")) # 子线程结束时激活
self.workThread.finished.connect(lambda: self.workThread.deleteLater()) # 释放子线程
# s6. 开启子线程
self.workThread.start()
# 布局
self.mainLayout = QVBoxLayout()
self.mainLayout.addWidget(self.label)
self.setLayout(self.mainLayout)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
方法2:实例化创建多线程
- 在子线程中自定义信号
- 在子线程中进行信号的触发
- 在主线程中实例化子线程
- 在主线程中实例化QThread类
- 在主线程中将子线程用
moveToThread()
方法绑定到QThread - 在主线程中对子线程的信号进行绑定
- 在主线程中,QThread开始时调用子线程类中的方法
- 在主线程中开启子线程
import time
from PySide6.QtCore import *
from PySide6.QtWidgets import *
# 子线程类
class WorkThread(QObject):
# s1. 自定义信号
signal = Signal(str)
def __init__(self):
super().__init__()
def runFunction(self):
for i in range(10):
# s2. 信号触发
self.signal.emit(str(i)) # 发送信号
time.sleep(1)
# 主线程
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# 创建一个标签,用于显示子线程的信号
self.label = QLabel()
# s3. 实例化子线程
self.workThread = WorkThread() # 用self实例化,防止子线程被回收
# s4. 实例化QThread类
self.thread = QThread()
# s5. 将子线程绑定到QThread
self.workThread.moveToThread(self.thread)
# s6. 对子线程的信号进行绑定
self.workThread.signal.connect(lambda x: self.label.setText(f"当前的值为:{x}")) # 将信号连接到标签
# s7. QThread开始时,调用子线程类中的方法
self.thread.started.connect(self.workThread.runFunction)
# QThread结束时激活
self.thread.finished.connect(lambda: print("Finished"))
# s8. 开启子线程
self.thread.start()
# 布局
self.mainLayout = QVBoxLayout()
self.mainLayout.addWidget(self.label)
self.setLayout(self.mainLayout)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
二、主线程向子线程传递信号
在子线程的 __init__()
方法中设置形参,在主线程实例化子线程时传入消息。
import time
from PySide6.QtCore import *
from PySide6.QtWidgets import *
# 子线程类:继承自QThread类
class WorkThread(QThread):
# 自定义信号
signal = Signal(str)
# 在 __init__() 方法中接收主线程的信号
def __init__(self, message):
super().__init__()
self.message = message
# 重写 run() 方法
def run(self):
# 子线程向主线程发送信号
self.signal.emit(f"子线程接收到信息:{self.message}")
# 主线程
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# 创建一个标签,用于显示子线程的信号
self.label = QLabel()
# 实例化子线程,并传入发送给子线程的消息
self.workThread = WorkThread("这是主线程发给子线程的信息!")
# 对子线程的信号进行绑定
self.workThread.signal.connect(lambda message: self.label.setText(message))
# 开启子线程
self.workThread.start()
# 布局
self.mainLayout = QVBoxLayout()
self.mainLayout.addWidget(self.label)
self.setLayout(self.mainLayout)
if __name__ == "__main__":
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
三、多线程的阻塞和删除(释放)
多线程的阻塞:
在主线程中,调用子线程实例化对象的 wait()
方法,可以对子线程进行阻塞,直到子线程方法运行结束或返回值,才继续运行。如:
self.workThread.wait()
多线程的删除(释放):
在主线程中,调用子线程实例化对象的 deleteLater()
方法,可以对子线程进行删除,该方法通常和子线程对象的 finished()
配合使用,用于在子线程执行完成后释放内存。如:
self.workThread.finished.connect(lambda: self.workThread.deleteLater())
很高兴本文对你有用(*^_^*),如需转载请记得标明出处哟(☆▽☆):
本文来自博客园,作者:香菜大魔法师,原文链接:https://www.cnblogs.com/corianderfiend/p/18069120