Issue
I'm trying to use the pyqt qthread for multithreading program.
In the code, there are two different workers instance. I try to use signal and slot for data share. but it seemed that the signal is blocked until one of the qthread is finished.
this is the code.
from PyQt5.QtCore import QCoreApplication,QThread, QObject, pyqtSignal, pyqtSlot
import time
import sys
class Worker(QObject):
finished = pyqtSignal()
intReady = pyqtSignal(int)
@pyqtSlot()
def work(self): # A slot takes no params
for i in range(1, 10):
time.sleep(1)
self.intReady.emit(i)
self.finished.emit()
class Worker2(QObject):
finished = pyqtSignal()
intReady = pyqtSignal(int)
@pyqtSlot()
def work(self): # A slot takes no params
for i in range(1, 10):
time.sleep(1)
self.intReady.emit(i)
self.finished.emit()
@pyqtSlot(int)
def revsignal(self, val):
print("hello rev a signal"+str(val))
def updateLabel(val):
print("updateLable "+str(val))
app = QCoreApplication(sys.argv)
# 1 - create Worker and Thread inside the Form
worker = Worker() # no parent!
thread = QThread() # no parent!
worker2 = Worker2()
thread2 = QThread()
worker.intReady.connect(updateLabel)
worker.intReady.connect(worker2.revsignal)
worker.moveToThread(thread)
worker.finished.connect(thread.quit)
thread.started.connect(worker.work)
# self.thread.finished.connect(app.exit)
worker2.moveToThread(thread2)
worker2.finished.connect(thread2.quit)
thread2.started.connect(worker2.work)
thread2.finished.connect(app.exit)
thread2.start()
print("after thread2 start")
thread.start()
print("after thread1 start.")
sys.exit(app.exec_())
and the output is here
after thread2 start
after thread1 start.
updateLable 1
updateLable 2
updateLable 3
updateLable 4
updateLable 5
updateLable 6
updateLable 7
updateLable 8
updateLable 9
hello rev a signal1
hello rev a signal2
hello rev a signal3
hello rev a signal4
hello rev a signal5
hello rev a signal6
hello rev a signal7
hello rev a signal8
hello rev a signal9
Process finished with exit code 0
i don't know why the worker2 thread can't receive the signal as soon as the work1 emit the signal. until the work1 thread ended.
Any help is greatly appreciated!
Solution
First thing is that all slots should be members of a class which inherits from QObject
. So make a class like this
class Manager(QObject):
@pyqtSlot(int)
def updateLabel(self, val):
print("updateLable "+str(val))
manager = Manager()
Next, as per the docs here, there is an additional argument which can be passed to connect
to control the behavior of cross-thread signal processing. You need to change three lines.
from PyQt5.QtCore import QCoreApplication, QThread, QObject, pyqtSignal, pyqtSlot, Qt
to get the Qt namespace, and both of
worker.intReady.connect(manager.updateLabel, type=Qt.DirectConnection)
worker.intReady.connect(worker2.revsignal, type=Qt.DirectConnection)
to set the connection type.
Answered By - buck54321
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.