【问题标题】:Running multiple background threads using QThread in PyQt5在 PyQt5 中使用 QThread 运行多个后台线程
【发布时间】:2021-08-11 14:30:03
【问题描述】:

调用多个线程时遇到问题。我没有运气。运行第一个定义(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)”但仍然没有运气。

【问题讨论】:

    标签: python pyqt5 qthread


    【解决方案1】:

    "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()
    

    【讨论】:

    • 可以在 1 个定义中运行多个返回发射吗?就像我想要 def procCounter(self) 发出 2 个项目/计数一样??? @eyllanesc
    【解决方案2】:

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

    【讨论】:

    • 您所指出的将导致 procCounter 在主线程上运行,从而导致 GUI 冻结
    猜你喜欢
    • 2018-07-20
    • 2017-09-24
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    相关资源
    最近更新 更多