dimanche 11 septembre 2016

How to invoke QMetaMethod with an array of QStrings?

QMetaObject system provides some basic reflection API. What I want to do is to call given slot or method that's available through this system.

However, the arguments and names of method are initially all QString values. The documentation shows an example:

QString retVal;
QByteArray normalizedSignature = QMetaObject::normalizedSignature("compute(QString, int, double)");
int methodIndex = obj->metaObject()->indexOfMethod(normalizedSignature);
QMetaMethod method = obj->metaObject()->method(methodIndex);
method.invoke(obj,
              Qt::DirectConnection,
              Q_RETURN_ARG(QString, retVal),
              Q_ARG(QString, "sqrt"),
              Q_ARG(int, 42),
              Q_ARG(double, 9.7));

If the "compute" slot does not take exactly one QString, one int and one double in the specified order, the call will fail.

Emphasis mine. Now with this example, I'm pretty clueless. It's clearly using templates, which are useless in dynamic context. I don't really see a purpose in using this API statically, when I could just as well call the method directly.

So let's say I have this function:

void invokeSlot(QObject* target, const QString& slotName, const QStringList& arguments) {
    // This is how I can get list of overloads by given name
    const QMetaObject* obj = target_->metaObject();
    QList<QMetaMethod> overloads;
    for (int i = 0, l = obj->methodCount(); i < l; ++i) {
        const QMetaMethod method = obj->method(i);
        if( method.name() == name )
            overloads.append(method);
    }        
    // Now how to convert the arguments?
}

You can assume that I have prepared this method for type conversion:

QVariant convertType(const QString& source, const QVariant::Type requiredType);

But how to pass the arguments even if I chose correct overload and convert strings to QVariants of required type?





Aucun commentaire:

Enregistrer un commentaire