[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?


  • Moderators

    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.



  • Nope. Doesn't like void * either.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    @
    MyWidget.h

    class 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();
    @


  • Lifetime Qt Champion

    Wouldn't it be simpler to call
    @
    QObject pqPolly;
    QMetaObject::invokeMethod(pqBoutique, "purchaseParrot", Qt::DirectConnection,
    Q_RETURN_ARG(QObject
    , pqPolly));
    @

    ?



  • I tried that and it didn't work. That was the -problem I originally ran into- reason I started this discussion.


  • Lifetime Qt Champion

    Ok, strange...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.