4 QtCore = qt_compat.QtCore
9 _moduleLogger = logging.getLogger(__name__)
12 class QThread44(QtCore.QThread):
14 This is to imitate QThread in Qt 4.4+ for when running on older version
15 See http://labs.trolltech.com/blogs/2010/06/17/youre-doing-it-wrong
16 (On Lucid I have Qt 4.7 and this is still an issue)
19 def __init__(self, parent = None):
20 QtCore.QThread.__init__(self, parent)
26 class _ParentThread(QtCore.QObject):
28 def __init__(self, futureThread):
29 QtCore.QObject.__init__(self)
30 self._futureThread = futureThread
32 @qt_compat.Slot(object)
33 @misc.log_exception(_moduleLogger)
34 def _on_task_complete(self, taskResult):
35 on_success, on_error, isError, result = taskResult
36 if not self._futureThread._isRunning:
38 _moduleLogger.error("Masking: %s" % (result, ))
40 result = StopIteration("Cancelling all callbacks")
41 callback = on_success if not isError else on_error
45 _moduleLogger.exception("Callback errored")
48 class _WorkerThread(QtCore.QObject):
50 taskComplete = qt_compat.Signal(object)
52 def __init__(self, futureThread):
53 QtCore.QObject.__init__(self)
54 self._futureThread = futureThread
56 @qt_compat.Slot(object)
57 @misc.log_exception(_moduleLogger)
58 def _on_task_added(self, task):
59 if not self._futureThread._isRunning:
60 _moduleLogger.error("Dropping task")
62 func, args, kwds, on_success, on_error = task
65 result = func(*args, **kwds)
68 _moduleLogger.error("Error, passing it back to the main thread")
72 taskResult = on_success, on_error, isError, result
73 self.taskComplete.emit(taskResult)
76 @misc.log_exception(_moduleLogger)
77 def _on_stop_requested(self):
78 self._futureThread._thread.quit()
81 class FutureThread(QtCore.QObject):
83 _addTask = qt_compat.Signal(object)
84 _stopFutureThread = qt_compat.Signal()
87 QtCore.QObject.__init__(self)
88 self._thread = QThread44()
89 self._isRunning = False
90 self._parent = _ParentThread(self)
91 self._worker = _WorkerThread(self)
92 self._worker.moveToThread(self._thread)
94 self._addTask.connect(self._worker._on_task_added)
95 self._worker.taskComplete.connect(self._parent._on_task_complete)
96 self._stopFutureThread.connect(self._worker._on_stop_requested)
100 self._isRunning = True
103 self._isRunning = False
104 self._stopFutureThread.emit()
106 def add_task(self, func, args, kwds, on_success, on_error):
107 assert self._isRunning, "Task queue not started"
108 task = func, args, kwds, on_success, on_error
109 self._addTask.emit(task)