PySide6之多线程

一、QThread

方法1:子类化创建多线程

  1. 创建子线程,继承自QThread类
  2. 在子线程中自定义信号
  3. 在子线程中重写 run() 方法,进行信号的触发
  4. 在主线程中实例化子线程
  5. 在主线程中对子线程的信号进行绑定
  6. 在主线程中开启子线程
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:实例化创建多线程

  1. 在子线程中自定义信号
  2. 在子线程中进行信号的触发
  3. 在主线程中实例化子线程
  4. 在主线程中实例化QThread类
  5. 在主线程中将子线程用 moveToThread() 方法绑定到QThread
  6. 在主线程中对子线程的信号进行绑定
  7. 在主线程中,QThread开始时调用子线程类中的方法
  8. 在主线程中开启子线程
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())
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
PySide6中使用多线程可以通过`QThread`类实现。以下是一个简单的示例代码,演示了如何在PySide6中创建和启动一个新的线程: ```python from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton from PySide6.QtCore import QThread, Signal class WorkerThread(QThread): # 自定义信号,用于在线程完成时发出信号 finished = Signal() def run(self): # 在这里执行耗时的操作 # ... # 操作完成后发出finished信号 self.finished.emit() class MainWindow(QMainWindow): def __init__(self): super().__init__() self.button = QPushButton("Start Thread", self) self.button.clicked.connect(self.start_thread) def start_thread(self): self.button.setEnabled(False) # 创建并启动新的线程 self.thread = WorkerThread() self.thread.finished.connect(self.thread_finished) self.thread.start() def thread_finished(self): # 线程完成后的处理逻辑 self.button.setEnabled(True) if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() app.exec() ``` 在上面的示例中,`WorkerThread`类继承自`QThread`,并在`run`方法中执行耗时的操作。当操作完成后,通过发出自定义的`finished`信号,通知主线程操作已经完成。在`MainWindow`类中,当用户点击按钮时,会创建并启动一个新的线程,并在线程完成后进行相应的处理。 需要注意的是,PySide6的GUI元素只能在主线程中操作,所以如果需要在多线程更新UI,通常需要使用信号和槽机制来实现。在上面的示例中,我们通过自定义信号`finished`和槽函数`thread_finished`来实现线程完成后的UI更新

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香菜仙人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值