使用另一个 QML 对象作为参数从 C++ 调用 QML 函数 [英] call QML function from C++ with another QML object as parameter
问题描述
我有一个 QML 文件 Dialog.qml
是 ApplicationWindow
和 Tab.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屋!