[Python] PySide6 signal not emitting properly when passed to decorator

Discussão em 'Python' iniciado por Stack, Março 27, 2025.

  1. Stack

    Stack Membro Participativo

    I have this decorator in python 3.11 that sends a signal encoding the arguments to a function call that it decorates, here:

    def register_action(signal=None):
    def decorator(func):
    def wrapper(self, *args, **kwargs): # self is the first argument for instance methods
    result = func(self, *args, **kwargs)

    history = {'function': func.__name__,
    'args': args,
    'kwargs': kwargs
    }
    try:
    signal.emit(history, False)
    except Exception as e:
    self.logger.info(f'Unable to log tab action: {str(e)}')
    return result
    return wrapper
    return decorator


    The signal in question is defined in a class at the top, like so:

    class MetadataView(MetaView):
    logger = logging.getLogger(__name__)
    update_tab_action_history = Signal(object, bool)
    ...


    and the decorator is applied like this:

    @register_action(signal=update_tab_action_history)
    def _overlay_plot(self, parameters):
    ...


    However, when this is called, I get the following error:

    'PySide6.QtCore.Signal' object has no attribute 'emit'


    I am reasonably certain that PySide6.QtCore.Signal does in fact have an emit attribute, so something else is going wrong... Any suggestions would be appreciated.

    Some research suggests going further up the chain. The MetaView class from which my class inherits inherits from QWidget and another custom class that was put together to allow use of abc @abstractmethod with pyside6, which apparently do not play nice together:

    class MetaView(QWidget, metaclass=QWidgetABCMeta):
    def __init__(self):
    """
    Initialize the MetaTab with a blank plot canvas and a space for
    controls.
    """
    super().__init__()
    ...


    While the QWidgetABCMeta class looks like this:

    import abc
    from PySide6.QtWidgets import QWidget


    class QWidgetABCMeta(abc.ABCMeta, type(QWidget)):
    def __new__(mcls, name, bases, ns, **kw):
    cls = super().__new__(mcls, name, bases, ns, **kw)
    abc._abc_init(cls)
    return cls

    def __call__(cls, *args, **kw):
    if cls.__abstractmethods__:
    raise TypeError(f"Can't instantiate abstract class {cls.__name__} without an implementation for abstract methods {set(cls.__abstractmethods__)}")
    return super().__call__(*args, **kw)

    Continue reading...

Compartilhe esta Página