[Solved] Q_RETURN_ARG for QObject-derived type
-
I have an object that I receive as a QObject pointer. I can get and set properties and invoke void methods without any problem. However, getting a return value from a method is a problem. If the type is a standard type such as bool, I can grab it this way:
@
bool bReturn;
qMethod.invoke(pqObj, Q_RETURN_ARG(bool, bReturn));
@but if the return type is a QObject-derived class, I just can't get that value. QVariant doesn't work, and neither does QObject *. The type in question is registered with the QML engine. Is there a way I can get that type and use it in Q_RETURN_ARG?
-
Q_RETURN_ARG should work with QObject pointers. Since you say it does not in your case, however, you may try to use void * and then cast it to QObject.
-
Hi and welcome to devnet,
@
MyWidget.hclass MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget parent = 0);
Q_INVOKABLE QWidget me() { return this; }
};main.cpp
MyWidget widget;
QWidget retVal = Q_NULLPTR;
QMetaObject::invokeMethod(&widget, "me", Qt::DirectConnection,
Q_RETURN_ARG(QWidget, retVal));
qDebug() << retVal;
@Returns the right value.
Can you show your current function code and how you call it exactly ?
-
Hi, sorry for the delay in replying [I must have missed the email].
@
parrot.h:class Parrot : public QObject
{
Q_OBJECT
Q_PROPERTY(bool isDead READ isDead)
Q_PROPERTY(bool canVoom READ canVoom)public:
Parrot(QObject *parent = 0);
bool isDead() const { return true; }
bool canVoom() const { return false; }
Q_INVOKABLE int queryVolts() { return 4000; }};
boutique.h:
class Boutique : public QObject
{
Q_OBJECT
public:
explicit Boutique(QObject parent = 0);
Q_INVOKABLE bool isOpen();
Q_INVOKABLE Parrot purchaseParrot();
Q_INVOKABLE bool registerComplaint(Parrot *polly);};
boutique.cpp:
bool Boutique::isOpen()
{
return true;
}Parrot* Boutique::purchaseParrot()
{
Parrot *polly = new Parrot();
return polly;
}bool Boutique::registerComplaint(Parrot *polly)
{
bool bResult = polly->isDead();
qDebug("He's not dead: he's resting.");
bResult = polly->canVoom();
return bResult;
}main.cpp:
auto topLevelObject = engine.rootObjects().value(0); QObject * pqTop = qobject_cast<QObject *>(topLevelObject); QObject *pqBoutique = pqTop->findChild<QObject *>("myBoutique"); if (!pqBoutique) { qCritical("Error: QML Object \"myBoutique\" not found."); return -1; } int iMethod; QMetaMethod qMethod; bool bResult, bIsOpen, bIsDead; QObject *pqPolly; const QMetaObject *pqClass = pqBoutique->metaObject(); iMethod = pqClass->indexOfMethod("isOpen()"); qMethod = pqClass->method(iMethod); bResult = qMethod.invoke(pqBoutique, Q_RETURN_ARG(bool, bIsOpen)); // bResult = true iMethod = pqClass->indexOfMethod("purchaseParrot()"); qMethod = pqClass->method(iMethod); bResult = qMethod.invoke(pqBoutique, Q_RETURN_ARG(QObject *, pqPolly)); // bResult = false
@
-
Got it!
@
pqClass = pqBoutique->metaObject();
iMethod = pqClass->indexOfMethod("purchaseParrot()");
qMethod = pqClass->method(iMethod);
int iType = qMethod.returnType(); // some int
const char name = qMethod.typeName(); // "Parrot"
QVariant qv(iType, NULL);
void* data = qv.data();
bResult = qMethod.invoke(pqBoutique, QGenericReturnArgument(name, data));
bResult = qv.canConvert(QMetaType::QObjectStar); // true
QObject pqPolly = qv.value<QObject>();
bResult = pqPolly->property("isDead").toBool();
bResult = pqPolly->property("canVoom").toBool();
@ -
Wouldn't it be simpler to call
@
QObject pqPolly;
QMetaObject::invokeMethod(pqBoutique, "purchaseParrot", Qt::DirectConnection,
Q_RETURN_ARG(QObject, pqPolly));
@?
-
Ok, strange...