pyqtSignale werden in QThread worker nicht ausgegeben
Ich habe eine Implementierung von aBackgroundTask
Objekt, das wie folgt aussieht:
class BackgroundTask(QObject):
'''
A utility class that makes running long-running tasks in a separate thread easier
:type task: callable
:param task: The task to run
:param args: positional arguments to pass to task
:param kawrgs: keyword arguments to pass to task
.. warning :: There is one **MAJOR** restriction in task: It **cannot** interact with any Qt GUI objects.
doing so will cause the GUI to crash. This is a limitation in Qt's threading model, not with
this class's design
'''
finished = pyqtSignal() #: Signal that is emitted when the task has finished running
def __init__(self, task, *args, **kwargs):
super(BackgroundTask, self).__init__()
self.task = task #: The callable that does the actual task work
self.args = args #: positional arguments passed to task when it is called
self.kwargs = kwargs #: keyword arguments pass to task when it is called
self.results= None #: After :attr:`finished` is emitted, this will contain whatever value :attr:`task` returned
def runTask(self):
'''
Does the actual calling of :attr:`task`, in the form ``task(*args, **kwargs)``, and stores the returned value
in :attr:`results`
'''
flushed_print('Running Task')
self.results = self.task(*self.args, **self.kwargs)
flushed_print('Got My Results!')
flushed_print('Emitting Finished!')
self.finished.emit()
def __repr__(self):
return '<BackgroundTask(task = {}, {}, {})>'.format(self.task, *self.args, **self.kwargs)
@staticmethod
def build_and_run_background_task(thread, finished_notifier, task, *args, **kwargs):
'''
Factory method that builds a :class:`BackgroundTask` and runs it on a thread in one call
:type finished_notifier: callable
:param finished_notifier: Callback that will be called when the task has completed its execution. Signature: ``func()``
:rtype: :class:`BackgroundTask`
:return: The created :class:`BackgroundTask` object, which will be running in its thread.
Once finished_notifier has been called, the :attr:`results` attribute of the returned :class:`BackgroundTask` should contain
the return value of the input task callable.
'''
flushed_print('Setting Up Background Task To Run In Thread')
bg_task = BackgroundTask(task, *args, **kwargs)
bg_task.moveToThread(thread)
bg_task.finished.connect(thread.quit)
thread.started.connect(bg_task.runTask)
thread.finished.connect(finished_notifier)
thread.start()
flushed_print('Thread Started!')
return bg_task
Wie in meinen Dokumentenstrings angegeben, sollte dies mir erlauben, einen beliebigen Wert zu übergebencallable
und seine Argumente zubuild_and_run_background_task
, und nach Abschluss der Aufgabe sollte es die aufrufencallable
bestanden alsfinished_notifier
und töte den Faden. Allerdings wenn ich es mit folgendem wie laufefinished_notifier
def done():
flushed_print('Done!')
Ich erhalte folgende Ausgabe:
Setting Up Background Task To Run In Thread
Thread Started!
Running Task
Got My Results!
Emitting Finished!
Und das ist es. Der finished_notifier-Rückruf wird niemals ausgeführt, und die quit-Methode des Threads wird niemals aufgerufen, was darauf hindeutet, dassfinshed
signal inBackgroundTask
wird eigentlich nicht ausgestrahlt. Wenn ich mich jedoch binde anfinshed
direkt anrufenrunTask
direkt (nicht in einem thread), alles funktioniert wie erwartet. Ich bin sicher, ich habe gerade etwas Dummes verpasst, irgendwelche Vorschläge?