Coverage for vibefpmgui/background.py: 100%
24 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-11-01 20:51 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-11-01 20:51 +0000
1"""Blocking calls (a program run to completion, a slow server) on a pool
2thread, so the window never waits for them; the result comes back in the
3GUI thread."""
5from __future__ import annotations
7from collections.abc import Callable
9from qtpy.QtCore import QObject, QRunnable, QThreadPool, Signal
12class _Receiver(QObject):
13 """Brings a background call's result to the GUI thread (it lives there,
14 so its signal is delivered there) and hands it to ``then``."""
16 done = Signal(object)
18 def __init__(self, then, parent=None):
19 super().__init__(parent)
20 self._then = then
21 self.done.connect(self._deliver)
23 def _deliver(self, result):
24 self.deleteLater()
25 self._then(result)
28class _Call(QRunnable):
29 def __init__(self, fn, receiver: _Receiver):
30 super().__init__()
31 self.fn, self.receiver = fn, receiver
33 def run(self):
34 result = self.fn()
35 try:
36 self.receiver.done.emit(result)
37 except RuntimeError:
38 pass # (the window that asked has closed)
41def call_in_background(fn: Callable[[], object], then: Callable[[object], None], parent: QObject):
42 """Run ``fn()`` on a pool thread, then ``then(result)`` in the GUI thread
43 (not at all if ``parent`` is gone by then)."""
44 QThreadPool.globalInstance().start(_Call(fn, _Receiver(then, parent)))