From 96de1a261a6eeac4319eb27302c4a62975ef8f6e Mon Sep 17 00:00:00 2001 From: Talley Lambert Date: Sun, 20 Feb 2022 11:25:10 -0500 Subject: [PATCH] add signals_blocked util (#69) --- src/superqt/utils/__init__.py | 11 +++++++---- src/superqt/utils/_misc.py | 15 +++++++++++++++ tests/test_utils.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 src/superqt/utils/_misc.py create mode 100644 tests/test_utils.py diff --git a/src/superqt/utils/__init__.py b/src/superqt/utils/__init__.py index 3c9f41c..9b5594c 100644 --- a/src/superqt/utils/__init__.py +++ b/src/superqt/utils/__init__.py @@ -5,17 +5,20 @@ __all__ = ( "FunctionWorker", "GeneratorWorker", "new_worker_qthread", - "QMessageHandler", - "thread_worker", - "WorkerBase", - "qthrottled", "qdebounced", + "QMessageHandler", "QSignalDebouncer", "QSignalThrottler", + "qthrottled", + "signals_blocked", + "thread_worker", + "WorkerBase", ) + from ._ensure_thread import ensure_main_thread, ensure_object_thread from ._message_handler import QMessageHandler +from ._misc import signals_blocked from ._qthreading import ( FunctionWorker, GeneratorWorker, diff --git a/src/superqt/utils/_misc.py b/src/superqt/utils/_misc.py new file mode 100644 index 0000000..085f191 --- /dev/null +++ b/src/superqt/utils/_misc.py @@ -0,0 +1,15 @@ +from contextlib import contextmanager +from typing import TYPE_CHECKING, Iterator + +if TYPE_CHECKING: + from qtpy.QtCore import QObject + + +@contextmanager +def signals_blocked(obj: "QObject") -> Iterator[None]: + """Context manager to temporarily block signals emitted by QObject: `obj`.""" + previous = obj.blockSignals(True) + try: + yield + finally: + obj.blockSignals(previous) diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..f80c606 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,29 @@ +from unittest.mock import Mock + +from qtpy.QtCore import QObject, Signal + +from superqt.utils import signals_blocked + + +def test_signal_blocker(qtbot): + """make sure context manager signal blocker works""" + + class Emitter(QObject): + sig = Signal() + + obj = Emitter() + receiver = Mock() + obj.sig.connect(receiver) + + # make sure signal works + with qtbot.waitSignal(obj.sig): + obj.sig.emit() + + receiver.assert_called_once() + receiver.reset_mock() + + with signals_blocked(obj): + obj.sig.emit() + qtbot.wait(10) + + receiver.assert_not_called()