Source code for napari.utils.events.event_utils
from __future__ import annotations
import weakref
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from typing import Callable, Protocol
    class Emitter(Protocol):
        def connect(self, callback: Callable):
            ...
        def disconnect(self, callback: Callable):
            ...
[docs]def disconnect_events(emitter, listener):
    """Disconnect all events between an emitter group and a listener.
    Parameters
    ----------
    emitter : napari.utils.events.event.EmitterGroup
        Emitter group.
    listener : Object
        Any object that has been connected to.
    """
    for em in emitter.emitters.values():
        em.disconnect(listener) 
def connect_setattr(emitter: Emitter, obj, attr: str):
    ref = weakref.ref(obj)
    def _cb(*value):
        if (ob := ref()) is None:
            emitter.disconnect(_cb)
            return
        setattr(ob, attr, value[0] if len(value) == 1 else value)
    emitter.connect(_cb)
    # There are scenarios where emitter is deleted before obj.
    # Also there is no option to create weakref to QT Signal
    # but even if keep reference to base object and signal name it is possible to meet
    # problem with C++ "wrapped C/C++ object has been deleted"
    # In all of these 3 functions, this should be uncommented instead of using
    # the if clause in _cb but that causes a segmentation fault in tests
    # weakref.finalize(obj, emitter.disconnect, _cb)
def connect_no_arg(emitter: Emitter, obj, attr: str):
    ref = weakref.ref(obj)
    def _cb(*_value):
        if (ob := ref()) is None:
            emitter.disconnect(_cb)
            return
        getattr(ob, attr)()
    emitter.connect(_cb)
    # as in connect_setattr
    # weakref.finalize(obj, emitter.disconnect, _cb)
def connect_setattr_value(emitter: Emitter, obj, attr: str):
    """To get value from Event"""
    ref = weakref.ref(obj)
    def _cb(value):
        if (ob := ref()) is None:
            emitter.disconnect(_cb)
            return
        setattr(ob, attr, value.value)
    emitter.connect(_cb)
    # weakref.finalize(obj, emitter.disconnect, _cb)