从C++返回QJSValue到qml

问题描述 投票:0回答:1

我有以下函数,它返回一个 javascript 数组作为 QJSValue。但是当我从 QML 调用这个函数时,生成的对象始终是“未定义”。

class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY (QJSValue test READ test NOTIFY testChanged)

public:
    MyClass() {}

    QJSValue test()
    {
        QJSEngine engine;
        QJSValue l = engine.newArray(5);

        for (int i = 0; i < 5; i++) {
            l.setProperty(i, i);
        }

        return l;
    }

    static void RegisterTypes()
    {
        qmlRegisterUncreatableType<MyClass>("MyTypes", 1, 0, "MyClass", "Creation of MyClass type not supported");
    }

Q_SIGNALS:
    void testChanged();

}

int main() {
    QQmlApplicationEngine engine;

    MyClass mc;
    MyClass::RegisterTypes();
    engine.rootContext()->setContextProperty("myClass", &mc);

    // ...
}

这几乎正是QJSValue 上的 Qt 文档中建议使用数组的方式。

例如以下按钮始终输出“未定义”:

Button {
    onClicked: console.log(myClass.test)
}
c++ qt qml
1个回答
0
投票

回答您问题的重要部分写在本段落中。数组存储在创建它们的引擎的堆上。在你的情况下,你有两个独立的引擎。一个来自

QQmlApplicationEngine
,另一个是您在
test()
函数中创建的。两者都有一个堆并且彼此分离,这就是数组未定义的原因。基元不存储在堆上,这就是
return QJSValue(5)
在您的示例中起作用的原因。

要解决此问题,您可以将“主”引擎转发到您的

MyClass
并使用它来创建数组。

QQmlApplicationEngine engine;

MyClass mc(&engine);
MyClass::registerTypes();
engine.rootContext()->setContextProperty("myClass", &mc);
class MyClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QJSValue test READ test NOTIFY testChanged)

public:
    MyClass(QQmlEngine *engine)
        : m_engine(engine)
    {}

    QJSValue test()
    {
        QJSValue l = m_engine->newArray(5);

        for (int i = 0; i < 5; i++) {
            l.setProperty(i, i);
        }

        return l;
    }

    static void registerTypes()
    {
        qmlRegisterUncreatableType<MyClass>("MyTypes",
                                            1,
                                            0,
                                            "MyClass",
                                            "Creation of MyClass type not supported");
    }

signals:
    void testChanged();

private:
    QQmlEngine *m_engine = nullptr;
};

在这里您可以找到完整的工作示例。

© www.soinside.com 2019 - 2024. All rights reserved.