napari.qt.threading.GeneratorWorker¶
- class napari.qt.threading.GeneratorWorker(func: typing.Callable[[superqt.utils._qthreading._P], typing.Generator[superqt.utils._qthreading._Y, typing.Optional[superqt.utils._qthreading._S], superqt.utils._qthreading._R]], *args, SignalsClass: typing.Type[superqt.utils._qthreading.WorkerBaseSignals] = <class 'superqt.utils._qthreading.GeneratorWorkerSignals'>, **kwargs)[source]¶
Bases:
superqt.utils._qthreading.GeneratorWorker
[napari._qt.qthreading._Y
,napari._qt.qthreading._S
,napari._qt.qthreading._R
],napari._qt.qthreading._NotifyingMixin
Methods
autoDelete
(self)await_workers
([msecs])Ask all workers to quit, and wait up to msec for quit.
create
(Callable[[], None])pause
()Request to pause the worker.
quit
()Send a request to abort the worker.
resume
()Send a request to resume the worker.
run
()Start the worker.
send
(value)Send a value into the function (if a generator was used).
setAutoDelete
(self, bool)start
()Start this worker in a thread and add it to the global threadpool.
Request to pause the worker if playing or resume if paused.
work
()Core event loop that calls the original function.
Attributes
Whether the worker has been requested to stop.
Whether the worker is currently paused.
Whether the worker has been started
Details
- classmethod await_workers(msecs: Optional[int] = None) None ¶
Ask all workers to quit, and wait up to msec for quit.
Attempts to clean up all running workers by calling
worker.quit()
method. Any workers in theWorkerBase._worker_set
set will have this method.By default, this function will block indefinitely, until worker threads finish. If a timeout is provided, a
RuntimeError
will be raised if the workers do not gracefully exit in the time requests, but the threads will NOT be killed. It is (currently) left to the user to use their OS to force-quit rogue threads.Important
If the user does not put any yields in their function, and the function is super long, it will just hang… For instance, there’s no graceful way to kill this thread in python:
@thread_worker def ZZZzzz(): time.sleep(10000000)
This is why it’s always advisable to use a generator that periodically yields for long-running computations in another thread.
See this stack-overflow post for a good discussion on the difficulty of killing a rogue python thread:
- Parameters
msecs (int, optional) – Waits up to msecs milliseconds for all threads to exit and removes all threads from the thread pool. If msecs is None (the default), the timeout is ignored (waits for the last thread to exit).
- Raises
RuntimeError – If a timeout is provided and workers do not quit successfully within the time allotted.
- create(Callable[[], None]) QRunnable ¶
- quit() None ¶
Send a request to abort the worker.
Note
It is entirely up to subclasses to honor this method by checking
self.abort_requested
periodically in theirworker.work
method, and exiting ifTrue
.
- run() None ¶
Start the worker.
The end-user should never need to call this function. But it cannot be made private or renamed, since it is called by Qt.
The order of method calls when starting a worker is:
calls QThreadPool.globalInstance().start(worker) | triggered by the QThreadPool.start() method | | called by worker.run | | | V V V worker.start -> worker.run -> worker.work
This is the function that actually gets called when calling
QThreadPool.start(worker)()
. It simply wraps thework()
method, and emits a few signals. Subclasses should NOT override this method (except with good reason), and instead should implementwork()
.
- send(value: superqt.utils._qthreading._S)[source]¶
Send a value into the function (if a generator was used).
- setAutoDelete(self, bool)¶
- start() None ¶
Start this worker in a thread and add it to the global threadpool.
The order of method calls when starting a worker is:
calls QThreadPool.globalInstance().start(worker) | triggered by the QThreadPool.start() method | | called by worker.run | | | V V V worker.start -> worker.run -> worker.work
- work() Union[superqt.utils._qthreading._R, None, Exception] [source]¶
Core event loop that calls the original function.
Enters a continual loop, yielding and returning from the original function. Checks for various events (quit, pause, resume, etc…). (To clarify: we are creating a rudimentary event loop here because there IS NO Qt event loop running in the other thread to hook into)