c++qtqt5qmetaobject

Qt invokeMethod calling function having output argument


I am trying to figure out the usage of QMetaObject::invokeMethod. I have a function that has one argument(non-const QString), I want it to be the output, the function has no return value, calling invokeMethod on it always fails, while another function which has return value and no argument can be called successfully. Here are the code:

myclass.h

#include <QDebug>

class MyClass: public QObject
{
    Q_OBJECT
public:
    MyClass() {}
    ~MyClass() {}
public slots:
    QString func();
    void func2(QString& res);
};

myclass.cpp

#include "myclass.h"

QString MyClass::func()
{
    QString res = "func succeeded";
    qDebug() << res;
    return res;
}

void MyClass::func2(QString& res)
{
    res = "func2 succeeded";
    qDebug() << res;
    return;
}

main.cpp

#include <QCoreApplication>
#include "myclass.h"

int main(int argc, char *argv[])
{
    QString msg;
    MyClass myobj;

    QCoreApplication a(argc, argv);

    bool val = QMetaObject::invokeMethod(&myobj, "func", Q_RETURN_ARG(QString, msg));
    qDebug() << "func returns" << val;

    val = QMetaObject::invokeMethod(&myobj, "func2", Q_RETURN_ARG(QString, msg));
    qDebug() << "func2 returns" << val;

    int ret = a.exec();
    return ret;
}

Here is the result:

$ ./test
"func succeeded"
func returns true
QMetaObject::invokeMethod: No such method MyClass::func2()
Candidates are:
    func2(QString&)
func2 returns false

I tried many different ways, can't get it work, anyone knows the reason? Thanks in advance!


Solution

  • When using Q_RETURN_ARG is to get the value that the method returns, but if you want to pass some argument you must use Q_ARG:

    #include <QCoreApplication>
    #include "myclass.h"
    
    int main(int argc, char *argv[])
    {
        QString msg;
        MyClass myobj;
    
        QCoreApplication a(argc, argv);
    
        bool val = QMetaObject::invokeMethod(&myobj, "func", Q_RETURN_ARG(QString, msg));
        qDebug() << "func returns" << val;
    
        val = QMetaObject::invokeMethod(&myobj, "func2", Q_ARG(QString &, msg));
        qDebug() << "func2 returns" << val;
    
        int ret = a.exec();
        return ret;
    }
    

    Output:

    "func succeeded"
    func returns true
    "func2 succeeded"
    func2 returns true