1

我试图弄清楚 QMetaObject::invokeMethod 的用法。我有一个有一个参数的函数(非 const QString),我希望它成为输出,该函数没有返回值,在它上面调用 invokeMethod 总是失败,而另一个有返回值且没有参数的函数可以被调用成功地。这是代码:

我的班级.h

#include <QDebug>

class MyClass: public QObject
{
    Q_OBJECT
public:
    MyClass() {}
    ~MyClass() {}
public slots:
    QString func();
    void func2(QString& res);
};

我的类.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;
}

主文件

#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

试了很多方法,都不行,有大神知道原因吗?提前致谢!

4

2 回答 2

1

当使用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
于 2018-02-24T04:35:57.093 回答
1

错误消息说明了一切。该类没有带有签名的方法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);
于 2018-02-24T04:36:13.833 回答