有一个 QtThread 参考成员我的 GUI class - PyQt5

Have a QtThread reference members of my GUI class - PyQt5

所以我试图在我的 GUI 上多线程点击一个按钮,我遇到的问题是该函数需要引用我的 main class 中定义的东西,这似乎是不可能的......每个例子我看到看起来像这样:

class Window(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.clicksCount = 0
        self.setupUi()

    def setupUi(self):
        # Create and connect widgets
        self.countBtn = QPushButton("Click me!", self)
        self.countBtn.clicked.connect(self.countClicks)

    def countClicks(self):
        self.clicksCount += 1
        self.clicksLabel.setText(f"Counting: {self.clicksCount} clicks")

    def reportProgress(self, n):
        self.stepLabel.setText(f"Long-Running Step: {n}")

    def runLongTask(self):
        """Long-running task in 5 steps."""
        for i in range(5):
            sleep(1)
            self.reportProgress(i + 1)

app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec())

[在此处找到:https://realpython.com/python-pyqt-qthread/]

他们将着手使 运行LongTask 成为一个新线程。但它没有引用 Window class 的单个成员或用户输入。

我的 GUI 有很多需要在线程中引用的用户输入。这是我的示例的精简版:

class Window(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.connectSignalsSlots()

        self.line_names = ["Trigger", "Slave1"]
        self.sources = [self.cmbTriggerSource, self.cmbSlaveLED1_Source]

        for info in QtSerialPort.QSerialPortInfo.availablePorts():
            self.cmbSerialPort.addItem(info.portName())

        self.cmbSourceClosed()

    def connectSignalsSlots(self):
    self.btnSerialPortScan.clicked.connect(self.btnSerialPortScanClicked)
        self.btnConfigure.clicked.connect(self.btnConfigureClicked)
        self.btnTMInit.clicked.connect(self.btnTesterModule)

    def btnSerialPortScanClicked(self):
        self.cmbSerialPort.clear()
        for info in QtSerialPort.QSerialPortInfo.availablePorts():
            self.cmbSerialPort.addItem(info.portName())

    def btnConfigureClicked(self):
        # Open the serial port
        port = self.openSerialPort()
        message.append(self.sources[i].currentIndex())
        self.sendData(port, message)
        self.closeSerialPort(port)

    def btnTesterModule(self):
        port = self.openSerialPort2(self)

        devices = cm.devices_list()
        com_port = self.cmbSerialPort_tester.currentText()

        a = self.LEDfrom.value()
        b = self.LEDto.value() + 1

        for i in range(a, b):
            self.SetButtonColour(i, 0)
            message.append((self.tester_LED[2].value() >> 24) & 0xff)
            message.append((self.tester_LED[2].value() >> 16) & 0xff)
            message.append((self.tester_LED[2].value() >> 8) & 0xff)
            message.append(self.tester_LED[2].value() & 0xff)
            self.selectObject(port, 3)
            self.sendData(port, message)

其中 btnTesterModule 函数需要一段时间,需要在新线程中。如您所见,它引用了很多自我。对象,因此将其移动到新线程将不再允许它从 GUI 或函数引用这些变量中的任何一个。

有谁知道如何创建一个仍然可以访问我的 window 和 GUI 的新线程,并在按下该按钮时将线程初始化为 运行 所述功能?我只想使用基本的 python 线程,但为了使它变得更复杂,我需要这个按钮的进度条,一旦它可以 运行 而不会导致 GUI 崩溃,所以将需要插槽和信号,我知道使用 QtThreads

别担心,我想通了,如果您需要这样做,最好只使用标准 python 线程,因为 PyQt5 没有任何有效处理这种情况的方法。

像这样:

import threading

    def ScanButtonThread(self):
        t = threading.Thread(target=self.btnTesterModule)
        t.start()

然后将按钮连接到此功能而不是另一个。