QT QML 项目在 C++ 和 QML 中

QT QML Items both in C++ and QML

本文关键字:QML C++ 项目 QT      更新时间:2023-10-16

我的目标是在 qml 文件中描述一个 qml 项目,然后使用相应的C++类添加到该项目的可视化表示中。

我知道可以描述一个 qml 项目并在 qml 文件中使用它,并通过信号/插槽从 c++ 与它进行通信。

我也知道可以使用QQuickPaintedItem在C++中描述qml项目,并在qml文件中使用它(通过寄存器机制使其可用)。还有其他方法吗?

那么,实际的问题是可以将两者合并到一个项目中吗?所以,我想有一个 qml 项目和一个 c++ 类绘制相同的区域,例如,我有特定的 c++ OpenGL 代码和一个在 qml 中定义的带有鼠标区域的常用矩形框架。

在 Andrej 的提示之后,我决定通过创建一个派生自 QQuickPaintedItem 的包装类并重写 paint 方法来实现我的目标,即同时拥有 qml 表示和 C++ 渲染类。有了这个,我可以在代码中呈现到项目中。该项目在我的主 qml 文件中使用。

它是一个包装类,因为它加载了我想通过 QQmlComponent 显示的 qml 文件,该文件也创建了我想要显示的 QuickItem。我通过将加载/创建的项目的父项设置为我的包装类来做到这一点。所以在我的 QuickPaintedItem 类中(最好在 classstart 中完成,当引擎已经初始化时):

QQmlComponent component(engine,QUrl("qrc:/myqml.qml")); QObject* object = component.create(); QQuickItem* quickItem = qobject_cast<QQuickItem*>(object); quickItem->setParentItem(this);

然后渲染myqml.qml和我的绘画方法。我有一个中心位置,我可以同时使用两者。

在 Velkan 的评论之后,另一种方法是将组件的加载放在 Loader qml 项中:

Wrapper { Loader{ onQmlChanged: source = newQml } }

其中 onQmlChanged 将是一个消耗信号的插槽:

signal onQmlChanged(string newQml);

我不能说哪种方式在性能方面更好。在 qml 中定义结构似乎更容易、更清晰。与代码版本的区别在于,它在创建包装器时加载项目,因此在创建 main.qml 期间和显示之前。