Tristan Djahel
Tristan Djahel

Reputation: 1212

Qt - invokeMethod failed because of return value

Here is the method's prototype that I want to call :

const QString& FieldForm::getTitle(void) const;

I have to call this method via Qt function : invokeMethod.

Here is my invokeMethod call:

bool ok = QMetaObject::invokeMethod(obj, MethodeName.toStdString().c_str(), Qt::DirectConnection, Q_RETURN_ARG(const QString, ReturnValue));

ok is always set to false.

I think that the problem is my function returns a const QString&. How can I get the returned value with that?

Thanks

Edit: Without changing my method's prototype

Edit2: Code

main.cpp

int main(int argc, char **argv)
{
    qRegisterMetaType("FieldForm");
    qRegisterMetaType("FieldForm*");
    QApplication app(argc, argv);
    FieldForm *obj = new FieldForm;
    obj->setTitle("MyTitle");
    QString MethodName = "getTitle";
    QString ReturnValue;
    bool ok = QMetaObject::invokeMethod(obj, MethodName.toStdString().c_str(),  Qt::DirectConnection, Q_RETURN_ARG(QString, ReturnValue));
    return app.exec();
}

FieldForm.h

class FieldForm : public QObject
{
Q_OBJECT
private:
    QString Title;
public slots:
    const QString& getTitle(void) const
    {
        return (this->Title);
    }
};

Upvotes: 2

Views: 2539

Answers (2)

László Papp
László Papp

Reputation: 53165

The short answer is that you should not achieve this without modifying the signature, unfortunately. See the possible options below. Please pick up what suits you the best.

You should use QStringRef as in:

const QStringRef getTitle() { return &myString; }

and then:

QStringRef ReturnValue;
bool ok = QMetaObject::invokeMethod(obj, "getTitle",
                                    Qt::DirectConnection,
                                    Q_RETURN_ARG(QStringRef, ReturnValue));

It does change the signature, but it is done for good. Alternatively, you could look into if you can register the QString& meta type with qRegisterMetaType, but really, use cases like this is the reason behind the existence of QStringRef.

You could also use a pointer return value if you wish, or even just value type due to QString being Copy-On-Write. In that particular case, you could change to something like this:

// const return value type is not necessarily here though.
const QString getTitle() const { return myString; } 

and then:

QString ReturnValue;
bool ok = QMetaObject::invokeMethod(obj, "getTitle", Qt::DirectConnection,
                                    Q_RETURN_ARG(QString, ReturnValue));

It depends on your particular scenario, but these are the options in here.

Upvotes: 1

Archie
Archie

Reputation: 2672

The following code works for me:

QString res;

bool invoked = QMetaObject::invokeMethod(obj,
                                         methodName.toAscii(),
                                         Q_RETURN_ARG(QString, res));

I do not use slot notation however, but a Q_INVOKABLE prefix:

public:
    Q_INVOKABLE QString getTitle() const;

Upvotes: 0

Related Questions