Calling method with array or arguments using QueuedConnection

476 Views Asked by At

I want to call arbitrary slot of QObject in other thread.

I have:

                           |  Arguments:    | Can use QueuedConnection?
QMetaObject::invokeMethod  |  fixed number  | YES
qt_metacall                |  array         | NO

I want:

<something>                |  array         | YES

I don't want to do things like duplicating invokeMethod code based on the number of arguments.

Where to get invokeMethod that accepts array of arguments or how to make qt_metacall queued?

2

There are 2 best solutions below

0
On

Working around by creating array initialized by GenericArgument:

QGenericArgument args[] = {
            QGenericArgument(), ....... ,QGenericArgument(),};

for (int p = 0; p < parameterTypes.count(); ++p) {
    QVariant::Type type = QVariant::nameToType(parameterTypes.at(p));

    switch(type) {
    case QVariant::String:
        args[p] = Q_ARG(QString, obtainTheNextStringArgument());
        break;
    // the rest needed types here        
    }
}

mm.invoke(object, Qt::QueuedConnection, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8],args[9]);
0
On

You can either:

  1. write a signal with the same default parameters as the slot you want to call, connect it to the slot with Qt::QueuedConnection and call the signal with qt_metacall and your array, or
  2. write a QObject derived class that:
    • takes your parameter array as parameter for its constructor, and stores it internally,
    • calls QMetaObject::invokeMethod in the constructor with Qt::QueuedConnection to invoke a slot without parameter which will call qt_metacall with the stored parameter array before deleting the QObject.

Internally Qt uses the 2nd method but with a internal class: QMetaCallEvent (in corelib/kernel/qobject_p.h) and postEvent instead of a signal/slot connection.