Qt invokeMethod вызывающая функция, имеющая выходной аргумент

Я пытаюсь выяснить использование QMetaObject::invokeMethod. У меня есть функция, которая имеет один аргумент (неконстантный QString), я хочу, чтобы она была выходной, функция не имеет возвращаемого значения, вызывая invokeMethod для нее всегда происходит сбой, в то время как другая функция, которая имеет возвращаемое значение и не имеет аргумента, может быть вызвана успешно. Вот код:

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;
}

Вот результат:

$ ./test
"func succeeded"
func returns true
QMetaObject::invokeMethod: No such method MyClass::func2()
Candidates are:
    func2(QString&)
func2 returns false

Я пробовал много разных способов, не могу заставить его работать, кто-нибудь знает причину? Заранее спасибо!

2 ответа

Решение

При использовании Q_RETURN_ARG нужно получить значение, которое возвращает метод, но если вы хотите передать какой-то аргумент, вы должны использовать 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;
}

Выход:

"func succeeded"
func returns true
"func2 succeeded"
func2 returns true

Сообщение об ошибке говорит обо всем. У класса нет метода с подписью MyClass:func2(),

Вы объявили функцию для подписи: void func2(QString&), который не совпадает с QString& func2(), Тот факт, что вы используете параметр функции в качестве возвращаемого значения, не имеет ничего общего с тем, как Qt сигнализирует и слотами кодирует имена методов или ищет их, и фактически вообще не имеет ничего общего с сигнатурой вызова. Сигнатура вызова - что бы это ни было, и Qt не может предсказать, как вы собираетесь использовать параметры.

Самое простое решение - изменить способ вызова метода. Тебе нужно иметь

QMetaObject::invokeMethod(&myobj, "func2", Q_ARG(QString, msg));

или, что еще лучше, используя безопасные для Qt 5.0+ сигналы и слоты.

QMetaObject::invokeMethod(&myobj, &MyClass::func2, &msg);
Другие вопросы по тегам