Как перехватить ВСЕ сигналы, испускаемые данным событием в Qt?

Я могу представить, что их может быть довольно много в зависимости от события, но в то же время я думаю, что это может быть лучшим способом отладки и интересным уроком.

Зачем мне это нужно? Я использую некоторый пользовательский класс, основанный на QWidget, который не расширяется, когда я отсоединяю QDockWidget на основе того же окна. Знание того, какие сигналы испускаются при отсоединении этого виджета док-станции, помогло бы мне выбрать, какой метод мне нужно перезаписать в моем пользовательском классе.

Другими словами, я не хочу проверять каждый возможный сигнал из документации, а просто смотрю, какие сигналы испускаются, когда я выполняю какое-то действие в своем приложении.


person Piotr Byzia    schedule 15.01.2010    source источник


Ответы (5)


Это невозможно с любым общедоступным API.

Но если вы поместите свой код в модульный тест на основе QTestLib, вы можете запустить модульный тест с -vs, чтобы распечатать каждый излучаемый сигнал.

person rohanpm    schedule 15.01.2010

Вы можете взглянуть на класс QSignalSpy. Я думаю, что вам нужно вручную подключить сигнал, который вы хотите шпионить.

person gregseth    schedule 15.01.2010

Я не думаю, что это возможно с Qt. Ты сможешь

  • перечислить все сигналы класса, используя QMetaObject::method и QMetaMethod::methodType;
  • прикрепите один из ваших собственных слотов ко всем этим сигналам;
  • проверьте, кто вызвал слот, используя QObject::sender.

Но я застрял после этого. Я не думаю, что, кроме отправителя, можно получить какую-либо информацию о том, как был вызван слот.

person mtvec    schedule 15.01.2010
comment
Спасибо за совет! Как мне это сделать? QMetaObject::method запрашивает параметр. Я не уверен, что мне нужно, чтобы пройти его. - person kayleeFrye_onDeck; 07.05.2016

Если вы используете PyQT5 вместо Qt5, вы можете использовать возможности самоанализа Python, чтобы найти все сигналы любого класса и подключить их к фиктивному слоту (фиктивному объекту).

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from typing import Iterable

from PyQt5.QtCore import pyqtBoundSignal
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import QObject


def list_all_signals(obj: QObject) -> Iterable[pyqtBoundSignal]:
    attr_names = dir(obj)
    attributes = (getattr(obj, attr_name) for attr_name in attr_names)
    connectable = filter(lambda l: hasattr(l, "connect"), attributes)

    return connectable


class SignalListener(QObject):
    @pyqtSlot()
    def universal_slot(self, *args, **kwargs):
        print("Signal caught" + 30 * "-")
        print("sender:", self.sender())
        meta_method = (
            self.sender().metaObject().method(self.senderSignalIndex())
        )
        print("signal:", meta_method.name())
        print("signal signature:", meta_method.methodSignature())


SIGNAL_LISTENER = SignalListener()


def spy_on_all_signals(
    obj: QObject, listener: SignalListener = SIGNAL_LISTENER
):
    for signal in list_all_signals(obj):
        signal.connect(SIGNAL_LISTENER.universal_slot)

Пустой слот теперь печатает информацию обо всех сигналах, излучаемых объектом. Например, если вы шпионите за случайным QLineEdit следующим образом:

some_line_edit = QLineEdit(self)
spy_on all_signals(some_line_edit)

Возможный лог входа и выхода из редактирования строки может выглядеть так:

Signal caught ------------------------------
sender: <PyQt5.QtWidgets.QLineEdit object at 0x7f220f7a3370>
signal: b'cursorPositionChanged'
signal signature: b'cursorPositionChanged(int,int)'
Signal caught ------------------------------
sender: <PyQt5.QtWidgets.QLineEdit object at 0x7f220f7a3370>
signal: b'selectionChanged'
signal signature: b'selectionChanged()'
Signal caught ------------------------------
sender: <PyQt5.QtWidgets.QLineEdit object at 0x7f220f7a3370>
signal: b'selectionChanged'
signal signature: b'selectionChanged()'
Signal caught ------------------------------
sender: <PyQt5.QtWidgets.QLineEdit object at 0x7f220f7a3370>
signal: b'editingFinished'
signal signature: b'editingFinished()'
person andrejr    schedule 31.07.2019

Ознакомьтесь с отслеживанием сигналов. Получил отличное представление о библиотеке QT и слежке за сигналами/слотами.

person Jure    schedule 03.11.2010