【python】pyqt中使用多线程处理耗时任务

在 PyQt 中使用多线程通常是为了避免界面冻结,特别是在执行耗时的任务时。PyQt 本身是基于 Qt 的,而 Qt 不允许在除主线程之外的线程中直接操作 GUI 元素。因此,任何涉及 GUI 更新的操作都应该在主线程中执行。

import sys  
import threading  
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLabel  
from PyQt5.QtCore import QThread, pyqtSignal  
import time  
  
# 定义一个线程类,继承自 QThread  
class WorkerThread(QThread):  
    # 定义一个信号,用于在主线程中更新文本  
    result_ready = pyqtSignal(str)  
  
    def run(self):  
        """线程执行的函数"""  
        # 模拟一个耗时的任务  
        time.sleep(5)  
        result = "任务完成"  
        # 发出信号,通知主线程  
        self.result_ready.emit(result)  
  
  
class MainWindow(QWidget):  
    def __init__(self):  
        super().__init__()  
        self.initUI()  
  
    def initUI(self):  
        self.setWindowTitle('PyQt 多线程示例')  
        self.setGeometry(300, 300, 300, 200)  
        layout = QVBoxLayout()  
          
        self.label = QLabel('等待任务...')  
        layout.addWidget(self.label)  
          
        self.button = QPushButton('开始任务')  
        self.button.clicked.connect(self.start_task)  
        layout.addWidget(self.button)  
          
        self.setLayout(layout)  
        self.show()  
  
    def start_task(self):  
        # 创建线程实例  
        self.thread = WorkerThread()  
        # 连接线程的信号到槽函数  
        self.thread.result_ready.connect(self.on_result_ready)  
        # 启动线程  
        self.thread.start()  
  
    def on_result_ready(self, result):  
        # 在主线程中更新标签文本  
        self.label.setText(result)  
        # 线程完成后,可以确保线程被清理  
        self.thread.quit()  
        self.thread.wait()  
  
  
if __name__ == '__main__':  
    app = QApplication(sys.argv)  
    window = MainWindow()  
    sys.exit(app.exec_())

传入一个函数进入线程中执行

import sys  
import threading  
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout  
from PyQt5.QtCore import QThread, pyqtSignal  
  
# 定义一个普通的 Python 函数  
def task_function(data):  
    # 执行一些任务,这里只是简单地打印数据  
    print(f"线程中执行函数,数据为: {data}")  
    # 模拟耗时操作  
    threading.Event().wait(2)  # 等待2秒  
  
# 定义一个线程类,继承自 QThread  
class WorkerThread(QThread):  
    # 定义一个信号,用于通知主线程任务完成  
    finished = pyqtSignal()  
  
    def __init__(self, function, data):  
        super().__init__()  
        # 将函数和数据作为属性保存  
        self.function = function  
        self.data = data  
  
    def run(self):  
        # 在线程中执行传入的函数  
        self.function(self.data)  
        # 发出信号通知任务完成  
        self.finished.emit()  
  
class MainWindow(QWidget):  
    def __init__(self):  
        super().__init__()  
        self.initUI()  
  
    def initUI(self):  
        self.setWindowTitle('PyQt 多线程示例')  
        self.setGeometry(300, 300, 300, 200)  
        layout = QVBoxLayout()  
          
        self.button = QPushButton('开始任务')  
        self.button.clicked.connect(self.start_task)  
        layout.addWidget(self.button)  
          
        self.setLayout(layout)  
        self.show()  
  
    def start_task(self):  
        # 定义要在线程中执行的数据  
        data = "Hello from thread"  
        # 创建线程实例,并传递函数和数据  
        self.thread = WorkerThread(task_function, data)  
        # 连接线程的信号到槽函数(这里只是打印消息,实际中可以做更多处理)  
        self.thread.finished.connect(self.on_thread_finished)  
        # 启动线程  
        self.thread.start()  
  
    def on_thread_finished(self):  
        # 线程完成后执行的代码  
        print("线程任务完成")  
  
if __name__ == '__main__':  
    app = QApplication(sys.argv)  
    window = MainWindow()  
    sys.exit(app.exec_())

 

posted @ 2024-04-25 18:26  海底淤泥  阅读(13)  评论(0编辑  收藏  举报