有没有办法从 PyQt5 中的 QThread return 数据类

Is there a way to return a dataclass from a QThread in PyQt5

我正在尝试使用 PyQt5 在 QThread 中更新数据class,但我似乎无法弄清楚如何从线程 return 更新 class。 我试过 finished = pyqtSignal(dataclass)finished = pyqtSignal(class)finished = pyqtSignal(<class>) 等,但其中 none 似乎有效。

下面是一段应该可以重现的精简代码。

import sys
from dataclasses import dataclass

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

@dataclass
class info():
    fname : str = "8888"
    lname : str = "8888"

class testThread(QObject):
    finished = pyqtSignal()

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

        self.data = data
        print(data)

    def run(self):
        print("Update dataclass")

        self.data.fname = "Bob"
        self.data.lname = "Alob"

        self.finished.emit(self.data)


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

        self.data = info()

        self.setWindowTitle("My App")
        self.resize(200, 200)

        self.lblOne = QLabel("Old Text", self)
        self.lblOne.move(40, 20)
        self.lblOne.resize(100,100)

        self.lblTwo = QLabel("Old Text", self)
        self.lblTwo.move(40, 40)
        self.lblTwo.resize(100,100)

        self.btn = QPushButton("Update Labels", self)
        self.btn.move(40, 100)
        self.btn.clicked.connect(self.runThread)

    def runThread(self):
        self.thread = QThread()
        self.worker = testThread(self.data)
        self.worker.moveToThread(self.thread)
        self.thread.started.connect(self.worker.run)
        self.worker.finished.connect(self.thread.quit)
        self.worker.finished.connect(self.worker.deleteLater)
        self.thread.finished.connect(self.thread.deleteLater)
        self.thread.start()

        self.thread.finished.connect(lambda: self.evt_onFinished(data))

    def evt_onFinished(self):
        "Update the labels with the information from the returned/updated dataclass"""

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

甚至可以从 PyQt5 中的 QThread return 数据class 吗?

Dataclasses 与任何 class 一样,因此您必须使用 class 的名称。另一方面,您正在连接 QThread 的完成信号而不是工作人员。

import sys
from dataclasses import dataclass


from PyQt5.QtCore import pyqtSignal, QObject, QThread
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QPushButton


@dataclass
class Info:
    fname: str = "8888"
    lname: str = "8888"


class testThread(QObject):
    finished = pyqtSignal(Info)

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

        self.data = data
        print(data)

    def run(self):
        print("Update dataclass")
        self.data.fname = "Bob"
        self.data.lname = "Alob"
        self.finished.emit(self.data)


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

        self.setWindowTitle("My App")
        self.resize(200, 200)

        self.lblOne = QLabel("Old Text", self)
        self.lblOne.move(40, 20)
        self.lblOne.resize(100, 100)

        self.lblTwo = QLabel("Old Text", self)
        self.lblTwo.move(40, 40)
        self.lblTwo.resize(100, 100)

        self.btn = QPushButton("Update Labels", self)
        self.btn.move(40, 100)
        self.btn.clicked.connect(self.runThread)

    def runThread(self):
        data = Info()
        self.thread = QThread()
        self.worker = testThread(data)
        self.worker.moveToThread(self.thread)
        self.thread.started.connect(self.worker.run)
        self.worker.finished.connect(self.evt_onFinished)
        self.worker.finished.connect(self.thread.quit)
        self.worker.finished.connect(self.worker.deleteLater)
        self.thread.finished.connect(self.thread.deleteLater)
        self.thread.start()

    def evt_onFinished(self, data):
        self.lblOne.setText(data.fname)
        self.lblTwo.setText(data.lname)


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