Qt 中查询信号与槽函数绑定关系的函数实现

已知 sender 和 receiver 的关系是

QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot);
QObject::connect(sender, &Sender::mySignal, receiver, &Receiver::mySlot2);

如何实现一个函数 enumSlot(QObject* reciever, QObject* sender, const QString& signName),其中 sender 的信号名字是 signName,想通过 signName 获取到 sender 的 signName 信号绑定了 receiver 的哪几个槽函数?(这个例子中,绑定了 2 个槽函数 &Receiver::mySlot&Receiver::mySlot2

可以使用 QMetaObject::indexOfMethodQMetaObject::method 获取 sender 的信号对应的方法索引,然后遍历 receiver 的所有槽函数,使用 QMetaObject::indexOfMethodQMetaMethod::methodSignature 获取槽函数的方法索引和方法签名,比较槽函数的方法签名是否与 sender 的信号对应的方法签名相同,如果相同则说明该槽函数与 sender 的信号绑定。具体实现如下:

void enumSlot(QObject* reciever, QObject* sender, const QString& signName)
{
    const QMetaObject* senderMetaObj = sender->metaObject();
    int signIndex = senderMetaObj->indexOfSignal(qPrintable(signName));
    if (signIndex == -1) {
        qWarning() << 'Invalid signal name: ' << signName;
        return;
    }
    QMetaMethod signMethod = senderMetaObj->method(signIndex);
    QByteArray signSignature = signMethod.methodSignature();

    const QMetaObject* recieverMetaObj = reciever->metaObject();
    for (int i = 0; i < recieverMetaObj->methodCount(); ++i) {
        QMetaMethod method = recieverMetaObj->method(i);
        if (!method.isValid() || !method.methodType() == QMetaMethod::Slot) {
            continue;
        }
        QByteArray methodSignature = method.methodSignature();
        if (methodSignature == signSignature) {
            qDebug() << 'Slot found: ' << recieverMetaObj->className() << '::' << method.name();
        }
    }
}

总结:

该函数通过遍历 receiver 的所有槽函数,并比较槽函数的方法签名与 sender 的信号方法签名,实现了查询 sender 的信号绑定了哪些 receiver 的槽函数的功能。

Qt 中查询信号与槽函数绑定关系的函数实现

原文地址: https://www.cveoy.top/t/topic/oUxG 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录