运行 在 PyQt5 中使用 QThread 的多个后台线程

Running multiple background threads using QThread in PyQt5

调用多线程时出现问题。我没有运气。运行第一个定义 (procCounter) 正常但不显示或 运行 第二个 (procCounter2)

下面是我的主要和我的工人:

    # main.py
    from PyQt5.QtCore import QThread
    from PyQt5.QtWidgets import QApplication, QLabel, QWidget, QGridLayout
    import sys
    import worker
    
    
    class Form(QWidget):
    
        def __init__(self):
           super().__init__()
           self.label = QLabel("0")
           self.label2 = QLabel("1")
    
           # 1 - create Worker and Thread inside the Form
           self.obj = worker.Worker()  # no parent!
           self.thread = QThread()  # no parent!
    
           # 2 - Connect Worker`s Signals to Form method slots to post data.
           self.obj.intReady.connect(self.onIntReady)
           self.obj.intReady.connect(self.onIntReady2)
    
           # 3 - Move the Worker object to the Thread object
           self.obj.moveToThread(self.thread)
    
           # 4 - Connect Worker Signals to the Thread slots
           self.obj.finished.connect(self.thread.quit)
    
           # 5 - Connect Thread started signal to Worker operational slot method
           self.thread.started.connect(self.obj.procCounter)
           self.thread.started.connect(self.obj.procCounter2)
    
           # * - Thread finished signal will close the app if you want!
           #self.thread.finished.connect(app.exit)
    
           # 6 - Start the thread
           self.thread.start()
    
           # 7 - Start the form
           self.initUI()
    
    
        def initUI(self):
            grid = QGridLayout()
            self.setLayout(grid)
            grid.addWidget(self.label,0,0)
            grid.addWidget(self.label2,0,1)
            self.move(300, 150)
            self.setWindowTitle('thread test')
            self.show()
    
        def onIntReady(self, i):
            self.label.setText("{}".format(i))
            print(i)
    
        def onIntReady2(self, i):
            #self.label2.setText("{}".format(i))
            print(i)
    
    app = QApplication(sys.argv)
    
    form = Form()
    
    sys.exit(app.exec_())

这是我的工人:

    # worker.py
    from PyQt5.QtCore import QThread, QObject, pyqtSignal, pyqtSlot
    import time
    
    
    class Worker(QObject):
        finished = pyqtSignal()
        intReady = pyqtSignal(int)
    
    
            @pyqtSlot()
            def procCounter(self): # A slot takes no params
              for i in range(1, 100):
                time.sleep(.5)
                self.intReady.emit(i)
    
              self.finished.emit()
    
            @pyqtSlot(int)
            def procCounter2(self): # A slot takes no params
               for i in range(1000):
                   time.sleep(.2)
                 self.intReady.emit(i)
    
            self.finished.emit()

我什至尝试在 worker 中添加 n 个额外的 pyqtSignal,例如:“intReady2 = pyqtSignal(int)”,然后在主要添加“self.obj.intReady2.connect(self.onIntReady2) " 但还是没有运气。

问题是self.thread.started.connect(self.obj.procCounter),需要换成self.thread.started.connect(lambda: self.obj.procCounter()) 更多信息

"obj" 存在于同一个线程中,因此当调用插槽时,它们将执行同一个线程,因此它执行的第一个函数将阻塞另一个。解决方案是创建 2 个工作线程,它们分别位于不同的线程中

class Worker(QObject):
    finished = pyqtSignal()
    intReady = pyqtSignal(int)

    @pyqtSlot()
    def procCounter(self):
        pass


class Worker1(Worker):
    @pyqtSlot()
    def procCounter(self):
        for i in range(1, 100):
            time.sleep(.5)
            self.intReady.emit(i)
        self.finished.emit()


class Worker2(QObject):
    @pyqtSlot(int)
    def procCounter(self):
        for i in range(1000):
            time.sleep(.2)
            self.intReady.emit(i)
        self.finished.emit()
self.obj1 = worker.Worker1()
self.thread1 = QThread()
self.obj1.moveToThread(self.thread1)
self.obj1.intReady.connect(self.onIntReady)
self.thread1.started.connect(self.obj.procCounter)

self.obj2 = worker.Worker2()
self.thread2 = QThread()
self.obj2.moveToThread(self.thread2)
self.obj2.intReady.connect(self.onIntReady2)
self.thread2.started.connect(self.obj2.procCounter)

self.thread1.start()
self.thread2.start()