使用 QQuickView 或 QQuickWidget 在 QWidget 应用程序中添加大量 QML 对象会带来性能问题
Posted
技术标签:
【中文标题】使用 QQuickView 或 QQuickWidget 在 QWidget 应用程序中添加大量 QML 对象会带来性能问题【英文标题】:Adding a high number of QML objects in a QWidget application using QQuickView or QQuickWidget poses performance problem 【发布时间】:2021-10-04 09:56:53 【问题描述】:我正在开发一个 Qt 应用程序,用户可以在其中将 QML 对象添加到 QGraphicsScene 中。列出了可用的 QML 对象,用户可以添加任意数量的对象。
到目前为止,我使用的是 QQuickWidgets。 QGraphicsScene 包含一个***小部件,它是我创建的所有 QQuickWidgets 的父级。它工作正常,但我有一个性能问题。对象数量多时,应用程序开始变慢,并占用过多的 RAM 空间(我创建的第一个示例超过 1.5 GB,包含 400 个对象)。
我认为它来自 Qt 处理 QQuickWidgets 的方式,并想尝试另一种方式,使用 QQuickViews。为此,我创建了一个根视图,在 QWidget 中进行了转换,因此我可以将其嵌入到我的视图中,这是一个 QWidget。然后我在根视图中为每个创建的对象添加一个新的 QQuickView。
创建根视图、它的容器和引擎:
_rootView = new QQuickWindow();
_rootView->resize(1024, 720);
_rootView->show();
QWidget *container = QWidget::createWindowContainer(_rootView, this);
container->resize(_rootView->size());
container->setObjectName("TopLevelQmlViewWidget");
_layout->addWidget(container);
_engine = new QQmlEngine(_rootView);
代表对象的 QQuickViews 的创建:
QQuickView *view = new QQuickView(_engine, _rootView);
view->setSource(url);
view->setResizeMode(QQuickView::SizeViewToRootObject);
view->show();
它可以工作,但问题是每个 QQuickView 都会创建自己的线程,这不会改变我处理它的方式,而是发生在内存中。我不明白为什么,因为我将它们重新设置为根视图。
所以我的问题如下:
1 - 有没有办法阻止 QQuickViews 创建自己的线程?
2 - 使用 QQuickViews 确实比使用 QQuickWidgets 消耗更少的内存吗?
3 - 如果不是,我如何在 QWidget 视图中添加大量 QML 对象而不消耗太多内存?
【问题讨论】:
【参考方案1】:我认为使用多个 QQuickViews 是个坏主意。一个应用程序通常只需要一个。我会看看QQmlComponent。这是一个例子:
QQmlComponent component(_engine, QUrl::fromLocalFile("MyItem.qml"));
QQuickItem *childItem = qobject_cast<QQuickItem*>(component.create());
childItem->setParentItem(_rootView);
【讨论】:
是的,我正在查看它,但不明白如何实现它。但是你的例子让我走上了一条好的道路,我能够弄清楚。现在我可以添加更多对象以减少内存。谢谢!【参考方案2】:我绝不是 QML 专家。但是,这里有一些我能想到的指针
-
Avoid mixing and matching QQuick: widget/View.
Consider creating objects dynamically
You can also make use of Loaders,但它们有少量额外开销。
考虑使用 stack/swipe view 之类的东西来尽量减少加载的对象数量。
为了获得最佳投资回报率,我首先尝试实现堆栈视图之类的东西,看看它对 RAM 有多大帮助。然后根据需要继续动态创建其他对象。
最后,我认为 QT 有一个工具可以让您在运行时查看 QML 树的内存量。你可以看看它,看看你最大的记忆猪在哪里。
【讨论】:
以上是关于使用 QQuickView 或 QQuickWidget 在 QWidget 应用程序中添加大量 QML 对象会带来性能问题的主要内容,如果未能解决你的问题,请参考以下文章