0

我正在开发一个 Qt 应用程序,其中用户可以在 QGraphicsScene 中添加 QML 对象。列出了可用的 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 对象而不消耗太多内存?

4

2 回答 2

2

我认为使用多个 QQuickViews 是个坏主意。一个应用程序通常只需要一个。我会看看QQmlComponent。这是一个例子:

QQmlComponent component(_engine, QUrl::fromLocalFile("MyItem.qml"));
QQuickItem *childItem = qobject_cast<QQuickItem*>(component.create());
childItem->setParentItem(_rootView);
于 2021-10-04T14:16:18.347 回答
1

我绝不是 QML 专家。但是,这里有一些我能想到的指针

  1. 避免混合和匹配 QQuick:小部件/视图。
  2. 考虑动态创建对象
  3. 考虑使用堆栈/滑动视图之类的东西来最小化加载对象的数量。

为了获得最佳投资回报率,我首先尝试实现堆栈视图之类的东西,看看它对 RAM 有多大帮助。然后继续根据需要动态创建其他对象。

最后,我认为 QT 有一个工具可以让您在运行时查看 QML 树的内存量。你可以看看那个,看看你最大的记忆猪在哪里。

于 2021-10-04T12:30:48.660 回答