orangewidget.utils.concurrent

General helper functions and classes for PyQt concurrent programming

class orangewidget.utils.concurrent.FutureWatcher(future=None, parent=None, **kwargs)[source]

Bases: QObject, PyOwned

An QObject watching the state changes of a concurrent.futures.Future

Note

The state change notification signals (done, finished, …) are always emitted when the control flow reaches the event loop (even if the future is already completed when set).

Note

An event loop must be running, otherwise the notifier signals will not be emitted.

Parameters:
  • parent (QObject) – Parent object.

  • future (Future) – The future instance to watch.

Example

>>> app = QCoreApplication.instance() or QCoreApplication([])
>>> f = submit(lambda i, j: i ** j, 10, 3)
>>> watcher = FutureWatcher(f)
>>> watcher.resultReady.connect(lambda res: print("Result:", res))
>>> watcher.done.connect(app.quit)
>>> _ = app.exec()
Result: 1000
>>> f.result()
1000
done(future: Future)

Signal emitted when the future is done (cancelled or finished)

finished(future: Future)

Signal emitted when the future is finished (i.e. returned a result or raised an exception - but not if cancelled)

cancelled(future: Future)

Signal emitted when the future was cancelled

resultReady(result: Any)

Signal emitted with the future’s result when successfully finished.

exceptionReady(exception: BaseException)

Signal emitted with the future’s exception when finished with an exception.

setFuture(future: Future) None[source]

Set the future to watch.

Raise a RuntimeError if a future is already set.

Parameters:

future (Future)

future() Future[source]

Return the future instance.

result() Any[source]

Return the future’s result.

Note

This method is non-blocking. If the future has not yet completed it will raise an error.

exception() BaseException | None[source]

Return the future’s exception.

Note

This method is non-blocking. If the future has not yet completed it will raise an error.

customEvent(self, QEvent)[source]
class orangewidget.utils.concurrent.FutureSetWatcher(futures: List[Future] | None = None, *args, **kwargs)[source]

Bases: QObject, PyOwned

An QObject watching the state changes of a list of concurrent.futures.Future instances

Note

The state change notification signals (doneAt, finishedAt, …) are always emitted when the control flow reaches the event loop (even if the future is already completed when set).

Note

An event loop must be running, otherwise the notifier signals will not be emitted.

Parameters:
  • parent (QObject) – Parent object.

  • futures (List[Future]) – A list of future instance to watch.

Example

>>> app = QCoreApplication.instance() or QCoreApplication([])
>>> fs = [submit(lambda i, j: i ** j, 10, 3) for i in range(10)]
>>> watcher = FutureSetWatcher(fs)
>>> watcher.resultReadyAt.connect(
...     lambda i, res: print("Result at {}: {}".format(i, res))
... )
>>> watcher.doneAll.connect(app.quit)
>>> _ = app.exec()
Result at 0: 1000
...
doneAt(index: int, future: Future)

Signal emitted when the future at index is done (cancelled or finished)

finishedAt(index: int, future: Future)

Signal emitted when the future at index is finished (i.e. returned a result)

cancelledAt(index: int, future: Future)

Signal emitted when the future at index was cancelled.

resultReadyAt(index: int, result: Any)

Signal emitted with the future’s result when successfully finished.

exceptionReadyAt(index: int, exception: BaseException)

Signal emitted with the future’s exception when finished with an exception.

progressChanged(donecount: int, count: int)

Signal reporting the current completed count

doneAll

Signal emitted when all the futures have completed.

setFutures(futures: List[Future]) None[source]

Set the future instances to watch.

Raise a RuntimeError if futures are already set.

Parameters:

futures (List[Future])

flush()[source]

Flush all pending signal emits currently enqueued.

Must only ever be called from the thread this object lives in (QObject.thread()).

wait()[source]

Wait for for all the futures to complete and enqueue notifications to this object, but do not emit any signals.

Use flush() to emit all signals after a wait()

class orangewidget.utils.concurrent.methodinvoke(obj, method, arg_types=(), *, conntype=2)[source]

A thin wrapper for invoking QObject’s method through QMetaObject.invokeMethod.

This can be used to invoke the method across thread boundaries (or even just for scheduling delayed calls within the same thread).

Note

An event loop MUST be running in the target QObject’s thread.

Parameters:
  • obj (QObject) – A QObject instance.

  • method (str) – The method name. This method must be registered with the Qt object meta system (e.g. decorated by a Slot decorator).

  • arg_types (tuple) – A tuple of positional argument types.

  • conntype (Qt.ConnectionType) – The connection/call type. Qt.QueuedConnection (the default) and Qt.BlockingConnection are the most interesting.

See also

QMetaObject.invokeMethod

Example

>>> app = QCoreApplication.instance() or QCoreApplication([])
>>> quit = methodinvoke(app, "quit", ())
>>> t = threading.Thread(target=quit)
>>> t.start()
>>> app.exec()
0
static from_method(method, arg_types=(), *, conntype=2)[source]

Create and return a methodinvoke instance from a bound method.

Parameters:
  • method (Union[types.MethodType, types.BuiltinMethodType]) – A bound method of a QObject registered with the Qt meta object system (e.g. decorated by a Slot decorators)

  • arg_types (Tuple[Union[type, str]]) – A tuple of positional argument types.

  • conntype (Qt.ConnectionType) – The connection/call type (Qt.QueuedConnection and Qt.BlockingConnection are the most interesting)

Returns:

invoker

Return type:

methodinvoke