8

I am looking through the Qt documentation. Is there a quick and dirty way to get a list of all signals that a widget can emit.

For example (withPyQt):

allSignalsList = thisWidget.getSignals()

Alternatively, is there is a nice place on the new Qt5 API that shows all the signals for a given QObject?

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
ADB
  • 1,210
  • 4
  • 15
  • 23

2 Answers2

11

There's no built-in method for listing signals, but normal python object introspection will get the information fairly easily:

from PyQt5 import QtCore, QtWidgets

def get_signals(source):
    cls = source if isinstance(source, type) else type(source)
    signal = type(QtCore.pyqtSignal())
    for subcls in cls.mro():
        clsname = f'{subcls.__module__}.{subcls.__name__}'
        for key, value in sorted(vars(subcls).items()):
            if isinstance(value, signal):
                print(f'{key} [{clsname}]')

get_signals(QtWidgets.QPushButton)

Output:

clicked [PyQt5.QtWidgets.QAbstractButton]
pressed [PyQt5.QtWidgets.QAbstractButton]
released [PyQt5.QtWidgets.QAbstractButton]
toggled [PyQt5.QtWidgets.QAbstractButton]
customContextMenuRequested [PyQt5.QtWidgets.QWidget]
windowIconChanged [PyQt5.QtWidgets.QWidget]
windowIconTextChanged [PyQt5.QtWidgets.QWidget]
windowTitleChanged [PyQt5.QtWidgets.QWidget]
destroyed [PyQt5.QtCore.QObject]
objectNameChanged [PyQt5.QtCore.QObject]

However, it's probably better to learn to use the Qt Documentation. If you go to the page for a Qt class, there's a Contents sidebar on the top-right which has links for the main member types. This usually includes a section for signals, but if it doesn't, you can drill down through the inherited classes until you find one.

So for example, the QPushButton page doesn't show a signals section, but it inherits QAbstractButton, which does have one.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • So for the classes that don't show signals on the 'contents' sidebar, you must look at the class from which it inherits. I see. Also, nice, instructive code snippet. – ADB Feb 01 '15 at 07:21
  • Is there a safe way to detect and skip all signals originating from the QObject base? – Silicomancer Aug 12 '21 at 22:47
  • 1
    @Silicomancer I updated the code example so that it breaks it down by class. Hopefully you can see how to adapt that to your own use-case. – ekhumoro Aug 13 '21 at 01:55
7

The trick is to use the QObject's meta object to iterate through the QObject's methods, then pick out the ones that have a signal type.

For example, this code snippet will print out the names of QThread's signals:

QThread thread;
QMetaObject metaObject = thread.staticMetaObject;
for (int i = 0; i < metaObject.methodCount(); i++) {
    QMetaMethod method = metaObject.method(i);
    if (method.methodType() == QMetaMethod::Signal) {
        qDebug() << "Signal: " << method.name();
    }
}

It should be trivial to adapt that to put the QMetaMethods into a QList or any other data structure.

MrEricSir
  • 8,044
  • 4
  • 30
  • 35