Reputation: 177
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!
Upvotes: 1
Views: 3151
Reputation: 6440
The error message says it all. The class does not have a method with signature MyClass:func2()
.
You've declared the function to have signature: void func2(QString&)
, which is not the same as QString& func2()
. The fact that you're using the function's parameter as a return value has nothing to do with how the Qt signals and slots code names methods or looks them up, and in fact, has nothing to do with the call signature at all. The call signature is whatever it is, and Qt cannot divine how you intend to use the parameters.
The easiest fix is to change how you're invoking the method. You need to have
QMetaObject::invokeMethod(&myobj, "func2", Q_ARG(QString, msg));
or, better yet, using Qt 5.0+ typesafe signals and slots.
QMetaObject::invokeMethod(&myobj, &MyClass::func2, &msg);
Upvotes: 1
Reputation: 243993
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
Upvotes: 1