如何从插槽中找出哪个信号称为此插槽?

时间:2014-12-15 02:30:33

标签: c++ qt qtcore qt-signals qmetaobject

我的意思是如果我有许多不同的信号连接到同一个插槽。我看到this问题,但在答案中无法理解the link。你能给我一个简单的例子吗?

1 个答案:

答案 0 :(得分:12)

我认为您可以使用此方法: [protected] int QObject::​senderSignalIndex() const

来自Qt文档:

  

返回调用当前正在执行的插槽的信号的元方法索引,它是sender()返回的类的成员。如果在信号激活的槽外调用,则返回-1。

     

对于具有默认参数的信号,此函数将始终返回包含所有参数的索引,无论哪个参数与connect()一起使用。例如,被破坏的信号(QObject * obj = 0)将具有两个不同的索引(有和没有参数),但是此函数将始终使用参数返回索引。当使用不同参数重载信号时,这不适用。

     

警告:此功能违反了面向对象的模块化原则。但是,当许多信号连接到单个插槽时,访问信号索引可能很有用。

     

警告:当通过Qt :: DirectConnection从与该对象的线程不同的线程调用插槽时,此函数的返回值无效。不要使用此函数在这种情况下。

     

此功能在Qt 4.8中引入。

以下是我为您创建的一个小示例,演示了它的工作原理:

#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

构建并运行

qmake && make && ./main

输出

"timeout"
"timeout()"