I have:
from PySide.QtCore import Signal, QObject
from multiprocessing import Pool
def some_computation():
pass
# ..some computations
return 'result'
class MyClass(QObject):
my_signal = Signal()
def __init__(self):
self.mylistwidget = # ... QListWidget from somewhere
# bind the signal to my slot
self.my_signal.connect(self.on_my_signal)
# this is called after computation thread is finished
def my_callback_fct(result):
# ..bla bla
self.my_signal.emit()
# this is the function I call
def do_some_async_computation(self)
pool = Pool(processes=2)
pool.apply_async(target=some_computation, callback=my_callback_fct)
# this is the slot
def on_my_signal(self):
self.mylistwidget.clear()
I read around stackoverflow that in order to change the gui from a secondary execution thread one must use slot-signal mechanism, which is what I did in MyClass , although when I call do_some_async_computation I would expect the pool to initiate a secondary thread for some_computation function ..which happens, after the computation is finished the my_callback_fct is executed accordingly, which emits a my_signal signal that is connected to the on_my_signal slot, which is executed as expected, but when altering the self.mylistwidget it gives a Runtime Error
/ QWidget runtime error redundant repaint detected
I haven't observed your actual error, but in a similar scenario we use a QueuedConnection to ensure the signal is passed correctly from one thread to the other. This is done automagically for some people if the objects in question belong to different threads (QObject have a notion of the QThread that owns them). But in your case, all is done on one object, so Qt can't know. Do
from PyQt5.QtCore import Qt
...
self.my_signal.connect(self.on_my_signal, Qt.QueuedConnection)
I solved this by using a QtCore.QThread
instead of multiprocessing.Pool
. I was thinking about the mechanism you talked about @deets and I said to myself that it should be in in the same context in order for Qt.QueuedConnection
to work, so that's why I wanted to go with QThread .
class MyComputationalThread(PySide.QtCore.QThread):
data_available = PySide.QtCore.Signal(str)
def run(self):
result = # ... do computations
serialized_result = json.dumps(result) # actually I use JSONEncoder here
self.data_available.emit(serialized_result)
... and in my MyClass
:
class MyClass(QObject):
# ...
mythread = MyComputationalThread()
# ...
def __init__(self):
# ...
self.mythread.connect(do_something_with_serialized_data, PySide.QtCore.Qt.QueuedConnection)
# ...
It works like a charm.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.