0

I have a QML scene that runs smoothly at 60fps.

I'm using a Loader to asynchronously load a component that has text with emojis. QT creates the Text object in the main thread and the qml profiler shows that it takes 183ms and I'm skipping frames since its taking more then 16ms to create the item. Here is an example with a timer that replicates the same

Component {
        id: textTest
        Text {
            anchors.centerIn: parent
            text: "Sample Test"
            font.pointSize: 32
            color: "blue"
        }
    }

    Timer {
        interval: 8000
        running: true
        repeat: false
        onTriggered: tester1.sourceComponent = textTest
    }

Loader {
        anchors.fill: parent
        id: tester1
        asynchronous: true

        visible: true
    }

Can I create the text item in another thread? So I can avoid dropping frames.

Can I subclass QQuickText and do the creation in another thread? I can do that with my custom QQuickItems but unsure how to do it with text

Andre Escudero
  • 373
  • 1
  • 3
  • 14
  • Your example won't _"replicate"_ your issue since we don't know what's in "test.qml" . – ניר Jul 28 '22 at 22:02
  • Also you can't create UI objects in another thread. [Ref](https://doc.qt.io/qt-6/thread-basics.html#gui-thread-and-worker-thread) – ניר Jul 28 '22 at 22:04
  • @ניר I have edited example to be replicated. The link you provided is not revelant for qml but it refers to qtwidgets. QML is using a scenegraph and you certainly render to another offscreen surface and notify when its ready to be displayed – Andre Escudero Jul 28 '22 at 22:25
  • I can't reproduce, works just fine. The `Timer` has no effect since he is assigning the same component so no loading is occurring, also it is not repeating. And as I said above there is no way to create UI objects on another thread, consider to use something like pagination on your emojis. – ניר Jul 28 '22 at 22:34
  • @ניר I found the solution by drawing the text in another thread based on. https://stackoverflow.com/questions/29631475/how-to-draw-text-in-qquickitem. I will post my answer once my implementation is done. Your comment that there is no way to create UI objects on another thread is completely wrong... – Andre Escudero Jul 28 '22 at 23:45
  • That is not my words, It is in the Qt docs I linked. – ניר Jul 28 '22 at 23:56

1 Answers1

0

I've noticed that rendering emojis at a large font size does appear to be slow. It feels as though the font loader is rastering the entire font at that size. To avoid that, we can consider finding an SVG equivalent of what we are rendering. Also, for dynamic creation of components, I generally prefer to use ListModel with Repeaters. This has the advantage of simplifying the dynamic creation and destruction of records by adding/removing items from the ListModel.

import QtQuick
import QtQuick.Controls
import QtQuick3D
Page {
    id: thisPage
    Repeater {
        model: listModel
        TestText {
            x: px
            y: py
        }
    }
    ListModel {
        id: listModel
    }
    Timer {
        id: timer
        repeat: false
        interval: 50
        onTriggered: {
             let px = Math.floor(Math.random() * thisPage.width);
             let py = Math.floor(Math.random() * thisPage.height);
             listModel.append({px,py});
             if (listModel.count < 20) Qt.callLater(start)
        }
    }
    footer: Button {
        text: qsTr("Start")
        onClicked: {
            listModel.clear();
            timer.restart();
        }
    }
}

//TestText.qml
import QtQuick
import QtQuick.Controls
Frame {
    background: Rectangle {
        border.color: "#e0e0e0"
    }
    Row {
        Text {
            text: "Sample Test"
            font.pointSize: 32
            color: "blue"
        }
        Image {
            width: 48
            height: 48
            source: "hand.svg"
            sourceSize: Qt.size(width, height)
        }
    }
}

//hand.svg
<?xml version="1.0" encoding="iso-8859-1"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 494.147 494.147" style="enable-background:new 0 0 494.147 494.147;" xml:space="preserve">
<path fill="orange" d="M455.84,172.391l-84.02-84.02c-13.278-13.278-34.805-13.278-48.083,0c-13.278,13.278-13.278,34.805,0,48.083l67.882,67.882
    l-7.071,7.071L197.847,24.707c-13.278-13.278-34.805-13.278-48.083,0c-13.278,13.278-13.278,34.805,0,48.083l123.062,123.062
    l-7.071,7.071L119.257,56.425c-13.278-13.278-34.805-13.278-48.083,0c-13.278,13.278-13.278,34.805,0,48.083l146.497,146.497
    l-7.071,7.071L87.538,135.015c-13.278-13.278-34.805-13.278-48.083,0s-13.278,34.806,0,48.083L162.516,306.16l-7.071,7.071
    l-97.404-97.404c-13.278-13.278-34.805-13.278-48.083,0c-13.278,13.278-13.278,34.805,0,48.083l177.181,177.181
    c51.077,51.077,134.185,51.077,185.262,0l83.439-83.439C506.917,306.576,506.916,223.468,455.84,172.391z"/>
</svg>

You can Try it Online!

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75