QML: 将JS对象传递给C++成员函数

5
我将尝试将一个JS对象(map)传递给一个具有以下签名的C++成员函数。
Q_INVOKABLE virtual bool generate(QObject* context);

通过使用
a.generate({foo: "bar"});

这个方法被调用了(通过断点检测),但传递的context参数是NULL。因为文档提到JS对象将作为QVariantMap传递,所以我尝试使用如下签名:

Q_INVOKABLE virtual bool generate(QVariantMap* context);

但是这在MOC期间失败了。使用

Q_INVOKABLE virtual bool generate(QVariantMap& context);

该方法会导致 QML 在运行时无法找到该方法(错误信息为“未知的方法参数类型: QVariantMap&”)。

文档中只有一个从 C++ 传递 QVariantMap 到 QML 的例子,没有反向的示例。

使用 public slot 而不是 Q_INVOKABLE 显示完全相同的行为和错误。

1个回答

5
不要使用引用将值从QML世界传递到CPP世界。 这个简单的例子有效:
test.h
#ifndef TEST_H
#define TEST_H

#include <QObject>
#include <QDebug>
#include <QVariantMap>

class Test : public QObject
{
    Q_OBJECT
public:
    Test(){}

    Q_INVOKABLE bool generate(QVariantMap context)
    {qDebug() << context;}
};

#endif // TEST_H

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "test.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    engine.rootContext()->setContextProperty(QStringLiteral("Test"), new Test());

    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    MouseArea
    {
        anchors.fill: parent
        onClicked:
        {
            Test.generate({foo: "bar"});
        }
    }
}

点击窗口,这将在输出控制台中打印以下信息:

QMap(("foo", QVariant(QString, "bar")))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接