如何在Qt中创建动态信号和插槽?

时间:2013-08-25 10:00:02

标签: c++ qt moc qt-signals

Qt中的信号/插槽机制是一种静态机制。这些类必须由moc编译器进行预处理 现在我想在运行时动态创建信号和插槽 我已经有了一个可行的解决方案,但我觉得我觉得自己像黑客一样,虽然我使用的是公开的方法 这是动态插槽的代码:

bool DynamicQObject::connectDynamicSlot(const QString &objectName, QObject *pSourceObject, QMetaMethod signalMethod)
{
    QByteArray slotName = signalMethod.name().prepend("on").append("(");
    QStringList parameters;
    for (int i = 0, j = signalMethod.parameterCount(); i < j; ++i)
    {
        parameters << QMetaType::typeName(signalMethod.parameterType(i));
    }
    slotName.append(parameters.join(",")).append(")");
    QByteArray theSignal = QMetaObject::normalizedSignature(signalMethod.methodSignature().constData());
    QByteArray theSlot = QMetaObject::normalizedSignature(slotName);
    if (!QMetaObject::checkConnectArgs(theSignal, theSlot))
    {
        return false;
    }

    int signalId = pSourceObject->metaObject()->indexOfSignal(theSignal);
    if (signalId < 0)
    {
        return false;
    }

    int slotId = slotIndices.value(theSlot, -1);
    if (slotId < 0)
    {
        slotId = slotList.size();
        slotIndices[theSlot] = slotId;
        slotList.append(createSlot(theSlot, objectName, signalMethod));
    }

    return QMetaObject::connect(pSourceObject, signalId, this, slotId + metaObject()->methodCount());
}

如您所见,我大量使用QMetaObject,特别是插槽的索引(方法计数)。
动态信号的代码是可比较的。

现在我的问题是:这个解决方案的未来证明如何,特别是因为我假设索引必须至少比methodCount()大一个?

2 个答案:

答案 0 :(得分:2)

  

现在我的问题是:这个解决方案的未来证明如何,特别是因为我假设索引必须至少比methodCount()大一个?

它现在应该有效。

至于未来的证据......可能是。该代码段使用了不受支持的功能,这意味着将来可能会破坏这些功能。它可能会继续发挥作用。

答案 1 :(得分:0)

作为一个单独的选项,如果你所有的东西本质上都非常相似(比如向量或其他东西),请考虑连接到 lambda 函数。例如:

_rid

其中 QObject::connect(iter->checkbox, &QCheckBox::stateChanged, [&, iter->startup_status](int new_val) { if (new_val == Qt::CheckState::Checked) { startup_status = true; } else { startup_status = false; } }); 是具有公共字段的结构/类

iter

通过这种方法,可以有数量可变的非常相似的“槽”(实际上不是槽,而是像槽一样)