从C ++调用QML函数,将另一个QML对象作为参数

时间:2014-11-23 18:38:36

标签: qt qml

我有一个QML文件Dialog.qmlApplicationWindowTab.qml ItemTabView中有Dialog.qml个标签由Tab.qml组成。我想在Tab.qml中创建Qt,将其信号连接到Qt中的类,并将该标签添加到Dialog。这是代码的相关部分:

//Tab.qml
Item {
    id: tb
    anchors.fill: parent
    //...here is signals and controls like RadioButtons and TextFields
}

//Dialog.qml
ApplicationWindow {
    visible: true
    title: "settings"
    flags: Qt.Dialog
    //...
    function addTabfromCpp(tab){
        frame.addTab("from c++", tab);
    }
    TabView {
        id:frame
        //...
    }
}

我知道当函数参数是基本类型(通过QML)时,如何从Qt调用QVariant函数。但是如何在参数为QQuickWindow或其他参数时调用函数,并且无法从中创建QVariant

1 个答案:

答案 0 :(得分:1)

您可以将QML对象ID作为函数参数传递。在C ++中,那些工作为QObject *。此外,除了ID之外,您还可以使用parent属性或children[indexOfChild]。请注意,您不会传递实际对象,因为这需要调用复制构造函数,并且对所有QObject派生类禁用复制,它通过引用传递,它在JS中使用{{1并且在C ++中使用var。以类似的方式,您可以使用QObject*将对象传递给QML。此外,您可能希望使用QObject*qRegisterMetaType()将自定义类型添加到Qt元类型,这样可以在QML中为您提供该类型的自动填充功能。

为了在QML上下文中公开C ++函数,您需要将这些函数设置为Q_DECLARE_METATYPE派生类的插槽或Q_INVOKABLE,实例化该类并使用QObject来公开它到QML。

或者,您可以将该对象注册到QML引擎,以便实例化它,您甚至可以通过this example.

在该对象的多个实例之间共享相同的数据。 编辑:好的,试试这个:

QML:

setContextProperty()

CPP:

ApplicationWindow {
    objectName: "blah"
    //...
    function foo(obj) { console.log(obj) }
}

,输出

QObject * root = engine.rootObjects().at(0);
QMetaObject::invokeMethod(root, "foo", Q_ARG(QVariant, QVariant::fromValue(root)));

似乎你必须将其作为qml: ApplicationWindow_QMLTYPE_11_QML_12(0x4121e70, "blah")

传递

但是,Q_ARG(QVariant, QVariant::fromValue(QObject*)不是一个对象(它是一个TabView.addTab()的实例)而是一个组件,即一个对象的原型。

您可以这样做的一种方法是:

Component