Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/superqt/utils/_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@


@contextmanager
def signals_blocked(obj: "QObject") -> Iterator[None]:
"""Context manager to temporarily block signals emitted by QObject: `obj`.
def signals_blocked(obj: "QObject", *others: "QObject") -> Iterator[None]:
"""Context manager to temporarily block signals emitted by QObjects.

Parameters
----------
obj : QObject
The QObject whose signals should be blocked.
The first QObject whose signals should be blocked.
*others : QObject
Additional QObjects whose signals should be blocked.

Examples
--------
Expand All @@ -26,8 +28,10 @@ def signals_blocked(obj: "QObject") -> Iterator[None]:
spinbox.setValue(10)
```
"""
previous = obj.blockSignals(True)
objs = (obj, *others)
previous = [o.blockSignals(True) for o in objs]
try:
yield
finally:
obj.blockSignals(previous)
for o, prev in zip(objs, previous):
o.blockSignals(prev)
37 changes: 35 additions & 2 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
from superqt.utils._util import get_max_args


def test_signal_blocker(qtbot):
"""make sure context manager signal blocker works"""
def test_signal_blocker_single(qtbot):
"""make sure context manager signal blocker works for one object"""

class Emitter(QObject):
sig = Signal()
Expand All @@ -35,6 +35,39 @@ class Emitter(QObject):
receiver.assert_not_called()


def test_signal_blocker_multiple(qtbot):
"""make sure context manager signal blocker works for multiple objects"""

class Emitter(QObject):
sig = Signal()

obj1 = Emitter()
obj2 = Emitter()
receiver1 = Mock()
receiver2 = Mock()
obj1.sig.connect(receiver1)
obj2.sig.connect(receiver2)

# make sure both signals work
with qtbot.waitSignal(obj1.sig):
obj1.sig.emit()
with qtbot.waitSignal(obj2.sig):
obj2.sig.emit()

receiver1.assert_called_once()
receiver2.assert_called_once()
receiver1.reset_mock()
receiver2.reset_mock()

with signals_blocked(obj1, obj2):
obj1.sig.emit()
obj2.sig.emit()
qtbot.wait(10)

receiver1.assert_not_called()
receiver2.assert_not_called()


def test_get_max_args_simple():
def fun1():
pass
Expand Down