使用另一个 QML 对象作为参数从 C++ 调用 QML 函数 [英] call QML function from C++ with another QML object as parameter

查看:13
本文介绍了使用另一个 QML 对象作为参数从 C++ 调用 QML 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a QML file Dialog.qml which is ApplicationWindow and Tab.qml which is Item. There are TabView in Dialog.qml which tabs is formed from Tab.qml. I want to create Tab.qml in Qt, connect its signals to classes in Qt and add that tab to Dialog. Here is relevant part of code:

//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
        //...
    }
}

当函数参数是原始类型时(通过 QVariant),我知道如何从 Qt 调用 QML 函数.但是当函数的参数是QQuickWindow或其他且无法创建QVariant时如何调用呢?

I know how to call QML functions from Qt when function parameters are primitive types(via QVariant). But how to call function when its parameter is QQuickWindow or other and it is not possible to create QVariant from it?

推荐答案

您可以将 QML 对象 id 作为函数参数传递就可以了.在 C++ 中,它们作为 QObject * 工作.此外,除了 id,您还可以使用 parent 属性或 children[indexOfChild].请注意,您没有传递实际的对象,因为这需要调用复制构造函数,并且所有 QObject 派生类都禁用复制,它是通过引用传递的,这在带有 var 并在 C++ 中使用 QObject*.以类似的方式,您可以使用 QObject* 将对象传递给 QML.此外,您可能希望使用 qRegisterMetaType()Q_DECLARE_METATYPE 将自定义类型添加到 Qt 元类型,这将在 QML 中为您提供该类型的自动完成功能.

You can pass QML object ids as function parameters just fine. In C++ those work as QObject *. Also, besides ids you can use the parent property, or children[indexOfChild]. Note that you don't pass the actual objects, since that would require invoking a copy constructor, and copying is disabled for all QObject derived classes, it is passed by reference, which works in JS with var and in C++ with QObject*. In a similar fashion, you can use QObject* to pass objects to QML. Additionally, you might want to add your custom types to the Qt metatypes with qRegisterMetaType() or Q_DECLARE_METATYPE, which will give you autocomplete for that type in QML.

为了在 QML 上下文中公开 C++ 函数,您需要将这些函数设为插槽或 QObject 派生类的 Q_INVOKABLE,实例化该类并使用 setContextProperty() 将其公开给 QML.

In order to expose C++ functions in the QML context, you need to make those functions either slots or Q_INVOKABLE of a QObject derived class, instantiate the class and use setContextProperty() to expose it to QML.

或者,您可以将该对象注册到 QML 引擎以便实例化它,您甚至可以按照 这个例子.

Or alternatively, you can register that object to the QML engine so you can instantiate it, you can even share the same data across multiple instances of that object by following this example.

好的,试试这个:

QML:

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

CPP:

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 的实例),而是组件,即对象的原型.

However, TabView.addTab() expects not an object (which is an instance of a Component) but a component, i.e. a prototype for an object.

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

One way you can do that is:

QObject * root = engine.rootObjects().at(0);
QQmlComponent comp(&engine, QUrl("qrc:/Test.qml"));
QMetaObject::invokeMethod(root, "addTab", Q_ARG(QVariant, QVariant::fromValue(&comp)));

这篇关于使用另一个 QML 对象作为参数从 C++ 调用 QML 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆