Dynamic return types
QMetaObject::invokeMethod allows calling methods on Qt objects dynamically. The method name is passed as a string, and the arguments are put together with QGenericArgument. If you haven’t read the documentation for the invokeMethod function, do so. It will open your eyes about Qt.
There’s just one problem: how do you handle a dynamic return value? QGenericReturnValue has to be set in advance with the type of value being returned. If we want to have a fully dynamic call, with even the return value type determined at runtime, then we need a way of inspecting a method to obtain its return type before we call it. After that, we can set up our QGenericReturnValue properly and call the method.
So, how do you get the return value type? Like this:
QByteArray getReturnType(const QObject *obj,
const QByteArray &method,
const QList<QByteArray> argTypes)
{
const QMetaObject *mo = obj->metaObject();
for(int n = 0; n < mo->methodCount(); ++n)
{
QMetaMethod m = mo->method(n);
QByteArray sig = m.signature();
int n = sig.indexOf('(');
if(n == -1)
continue;
QByteArray name = sig.mid(0, n);
if(name != method)
continue;
if(m.parameterTypes() != argTypes)
continue;
return m.typeName();
}
return QByteArray();
}
Now you can have some code:
class MyObject : public QObject
{
Q_OBJECT
...
public slots:
QString intToString(int x)
{
return QString::number(x);
}
};
MyObject *obj = ...
QByteArray methodName = "intToString";
QList<QByteArray> argTypes;
argTypes += "int";
QByteArray retType = getReturnType(obj, methodName, argTypes);
// the value of retType is now "QString"
At this point, we have the method name, the argument types, and the return type. For homework: figure out how to use this information in order to make an invokeMethod() call. I’ll explain how in a later article.


