Search code examples
c++qtqtcoreqt-signalsqmetaobject

How to find out from the slot which signal has called this slot?


I mean if I have many different signals which are connected to the same slot. I saw this question but can't understand the link in the answer. Can you give me simple example?


Solution

  • I think you can use this method: [protected] int QObject::​senderSignalIndex() const

    From Qt documentation:

    Returns the meta-method index of the signal that called the currently executing slot, which is a member of the class returned by sender(). If called outside of a slot activated by a signal, -1 is returned.

    For signals with default parameters, this function will always return the index with all parameters, regardless of which was used with connect(). For example, the signal destroyed(QObject *obj = 0) will have two different indexes (with and without the parameter), but this function will always return the index with a parameter. This does not apply when overloading signals with different parameters.

    Warning: This function violates the object-oriented principle of modularity. However, getting access to the signal index might be useful when many signals are connected to a single slot.

    Warning: The return value of this function is not valid when the slot is called via a Qt::DirectConnection from a thread different from this object's thread. Do not use this function in this type of scenario.

    This function was introduced in Qt 4.8.

    Here is a small example that I created for you that demonstrates how it works:

    #include <QTimer>
    #include <QMetaObject>
    #include <QMetaMethod>
    #include <QCoreApplication>
    #include <QDebug>
    #include <QObject>
    
    class Foo : public QObject
    {
        Q_OBJECT
        public slots:
            void mySlot() {
                QMetaMethod metaMethod = sender()->metaObject()->method(senderSignalIndex());
                qDebug() << metaMethod.name();
                qDebug() << metaMethod.methodSignature();
                qApp->quit();
            }
    };
    
    #include "main.moc"
    
    int main(int argc, char **argv)
    {
        QCoreApplication coreApplication(argc, argv);
        QTimer timer;
        Foo foo;
        QObject::connect(&timer, &QTimer::timeout, &foo, &Foo::mySlot);
        timer.setSingleShot(true);
        timer.start(1000);
        return coreApplication.exec();
    }
    

    main.pro

    TEMPLATE = app
    TARGET = main
    QT = core
    CONFIG += c++11
    SOURCES += main.cpp
    

    Build and Run

    qmake && make && ./main
    

    Output

    "timeout"
    "timeout()"