Home > front end >  Adding a high number of QML objects in a QWidget application using QQuickView or QQuickWidget poses
Adding a high number of QML objects in a QWidget application using QQuickView or QQuickWidget poses

Time:10-05

I'm developping a Qt application in which the user can add QML objects inside a QGraphicsScene. The available QML objects are listed and the user can add as many as he wants.

Until now, I used QQuickWidgets. The QGraphicsScene contains a top-level widget which is the parent of all the QQuickWidgets I create. It works fine, but I have a performance problem. With a high number of objects, the application starts to slow down, and takes too much space in RAM (more than 1.5 GB with the first example I created, containing 400 objects).

I thought it comes from the way QQuickWidgets are handled by Qt, and wanted to try another way, with QQuickViews. To do so I created a root view, converted in a QWidget so I can embed it in my view, which is a QWidget. Then I add a new QQuickView in the root view for each created object.

The creation of the root view, its container and the engine:

    _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);

The creation of the QQuickViews representing the objects:

    QQuickView *view = new QQuickView(_engine, _rootView);
    view->setSource(url);
    view->setResizeMode(QQuickView::SizeViewToRootObject);
    view->show();

It works, but the problem is that each QQuickView creates its own thread, which doesn't change the way I handle it but takes place in memory. I don't understand why, because I reparent them to the root view.

So my questions are the following :

1 - Is there a way to prevent the QQuickViews to create their own threads ?

2 - Is using QQuickViews, indeed, less memory-consuming than using QQuickWidgets ?

3 - If no, how can I handle adding a big number of QML objects in a QWidget view without consuming too much memory ?

CodePudding user response:

I think using multiple QQuickViews is a bad idea. An application usually only needs one. I would take a look at QQmlComponent instead. Here is an example:

QQmlComponent component(_engine, QUrl::fromLocalFile("MyItem.qml"));
QQuickItem *childItem = qobject_cast<QQuickItem*>(component.create());
childItem->setParentItem(_rootView);

CodePudding user response:

I'm by no means a QML expert. However, here are some pointers I can think of

  1. Avoid mixing and matching QQuick: widget/View.
  2. Consider creating objects dynamically
  3. Consider using something like a stack/swipe view to minimize amount of loaded objects.

For best ROI, I'd first try implementing something like stack view and see how much it may help with the RAM. Then go on to create other objects dynamically as needed.

Finally I think QT has a tool that lets you see during runtime the amount of memory of the QML tree. You can look at that and see where your biggest memory hogs are.

  • Related