pyqt6使用多线程,使前台展示和后台处理数据分线程进行

该代码示例展示了如何利用Python的PyQt库中的QThread和pyqtSignal处理Excel数据。它创建了三个线程:读取Excel文件,处理数据(将所有字符串转为大写),以及显示数据。数据在不同线程间通过pyqtSignal信号传递,确保主线程不被阻塞,提高程序响应性。
摘要由CSDN通过智能技术生成
import sys
import time
from PyQt6.QtWidgets import QApplication, QDialog, QLabel, QVBoxLayout
from PyQt6.QtCore import QThread, pyqtSignal
import pandas as pd


class ExcelReaderThread(QThread):
    data_read = pyqtSignal(pd.DataFrame)


    def __init__(self, file_path):
        super().__init__()
        self.file_path = file_path

    def run(self):
        # 读取Excel文件
        df = pd.read_excel(self.file_path)

        # 发送数据读取信号
        self.data_read.emit(df)


class DataProcessorThread(QThread):
    data_processed = pyqtSignal(pd.DataFrame)

    def __init__(self, data):
        super().__init__()
        self.data = data

    def run(self):
        # 处理数据,这里简单地将所有字符串转换为大写
        df = self.data.applymap(lambda x: x.upper() if isinstance(x, str) else x)
        # 发送数据处理信号
        self.data_processed.emit(df)


class DataDisplayerThread(QThread):
    data_displayed = pyqtSignal(pd.DataFrame)

    def __init__(self, data):
        super().__init__()
        self.data = data

    def run(self):
        # 模拟展示数据的过程,这里简单地打印数据
        print(self.data)
        # 发送数据展示信号
        self.data_displayed.emit(self.data)


class MainWindow(QDialog):
    def __init__(self):
        super().__init__()

        self.file_path = "example.xlsx"

        self.setWindowTitle("Excel Data Display")

        self.status_label = QLabel("Loading data...")
        self.data_label = QLabel("")

        layout = QVBoxLayout()
        layout.addWidget(self.status_label)
        layout.addWidget(self.data_label)
        self.setLayout(layout)

        self.reader_thread = ExcelReaderThread(self.file_path)
        self.reader_thread.data_read.connect(self.process_data)

        self.processor_thread = DataProcessorThread(None)
        self.processor_thread.data_processed.connect(self.display_data)

        self.displayer_thread = DataDisplayerThread(None)
        self.displayer_thread.data_displayed.connect(self.show_data)

        self.reader_thread.start()

    def process_data(self, data):
        self.status_label.setText("Processing data...")
        self.processor_thread.data = data
        self.processor_thread.start()

    def display_data(self, data):
        self.status_label.setText("Displaying data...")
        self.displayer_thread.data = data
        self.displayer_thread.start()

    def show_data(self, data):
        self.status_label.setText("Data displayed.")
        self.data_label.setText(str(data))


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

以上代码主要是使用了QThread和pyqtSignal来解决这个问题。
一、QThread类提供了一种在单独的线程中执行耗时操作的方法,从而避免阻塞主线程,提高了应用程序的响应速度和用户体验,MainWindow为主线程。
二、pyqtSignal 信号用来传递变量pd.DataFrame。
在PyQt中,pyqtSignal是一个信号/槽机制,用于在不同对象之间传递消息。可以将一个自定义的pyqtSignal信号与一个槽函数连接起来,当信号发射时,槽函数会自动被调用。在这个特定的用法中,pyqtSignal(pd.DataFrame)定义了一个可以传递pd.DataFrame类型数据的信号,在需要传递pd.DataFrame类型数据时,可以使用该信号进行传递。
三、DataProcessorThread(None) 初始化的时候不传入data,在self.processor_thread.data_processed.connect 中通过信号传入data数据。
举例
以上为什么不需要传递result参数
在PyQt的信号槽机制中,当信号连接到一个槽函数时,信号会自动将传递的参数列表传递给槽函数。在前面的例子中,当DataProcessor类中的dataProcessed信号发射时,该信号会自动将传递的pd.DataFrame类型数据作为参数传递给showResult槽函数。因此,在定义showResult槽函数时,不需要显式地指定result参数。

具体来说,在定义showResult槽函数时,可以将result参数作为槽函数的一个参数进行定义。当dataProcessed信号发射时,该信号会自动将传递的pd.DataFrame类型数据作为参数传递给showResult槽函数,从而在槽函数中可以直接访问该数据。
例如,可以将showResult槽函数定义为如下形式:

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.dataProcessor = DataProcessor()
        self.dataProcessor.dataProcessed.connect(self.showResult)
        ...
    
    def showResult(self, result: pd.DataFrame):
        # 在GUI界面上显示结果
        # result是传递过来的pd.DataFrame类型数据
        ...

在该定义中,showResult槽函数有一个result参数,用于接收传递的pd.DataFrame类型数据。当dataProcessed信号发射时,该信号会自动将传递的pd.DataFrame类型数据作为参数传递给showResult槽函数,从而在槽函数中可以直接访问该数据。
需要注意的是,当定义槽函数时,参数列表的类型和顺序需要与信号传递的参数列表的类型和顺序一致,否则会导致传递的参数无法被正确接收和处理。
四、pd.DataFrame类型数据作为参数传递时,实际上传递的是数据。在Python中,pd.DataFrame是pandas库中用于处理表格数据的主要数据结构之一。pd.DataFrame可以包含不同类型的数据,通常被表示为一个二维的表格,其中每一列可以是不同的数据类型,例如数值、字符串、日期等。
当pd.DataFrame类型数据作为参数传递时,实际上传递的是数据的引用。即使数据非常大,也不会在传递过程中进行复制,而是直接传递数据的引用。这样可以避免数据的不必要的复制和内存占用。在槽函数中,可以直接访问传递的数据,进行相应的处理和显示。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

金融小白数据分析之路

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

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

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

打赏作者

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

抵扣说明:

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

余额充值