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

时间:2017-11-14 13:34:43

标签: javascript c++ qt qml

我试图将JS对象(map)传递给带签名的C ++成员函数

Q_INVOKABLE virtual bool generate(QObject* context);

使用

a.generate({foo: "bar"});

调用该方法(通过断点检测),但传递的context参数为NULL。由于the documentation提到JS对象将作为QVariantMap传递,我已尝试使用签名

Q_INVOKABLE virtual bool generate(QVariantMap* context);

但在MOC期间失败了。使用

Q_INVOKABLE virtual bool generate(QVariantMap& context);

导致QML在运行时找不到该方法(错误消息是"未知方法参数类型:QVariantMap&")。

该文档仅提供了一个将QVariantMap从C ++传递到QML的示例,而不是另一个方向。

使用public slot代替Q_INVOKABLE会显示完全相同的行为和错误。

1 个答案:

答案 0 :(得分: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"});
        }
    }
}

在窗口中单击,这将在输出控制台中打印以下msg:

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