[Interest] QML: Considerations on an interesting design pattern that relies on JS engine's garbage collection
Fatih Uzunoğlu
fuzun54 at outlook.com
Thu Apr 10 23:05:14 CEST 2025
Hello,
I have recently discovered an interesting pattern, it seems really handy
to me. However, I wanted to ask for opinions if there are potential bad
sides so that I don't use this in more places.
This is easier to explain directly on an example:
Currently, `ScrollBar`'s documentation mentions its usage on a
`Flickable` as such (note that `ScrollBar.vertical` is a
`QQuickScrollBar` pointer, and not a component):
```
Flickable {
// ...
ScrollBar.vertical: ScrollBar { }
}
```
There are some problems with this suggestion:
- Disabling creation of the scroll bar, if where the `Flickable` re-used
does not want a scroll bar. Currently, QML engine does not seem to allow
a way to do that. Doing `ScrollBar.vertical: null` in where flickable is
re-used does not prevent creating the original `ScrollBar`. My
understanding is that, this is a long-standing problem.
- If `Flickable` wants to use a different type, this `ScrollBar` is
still created.
Maybe attached `ScrollBar` makes it sure to properly detach a scroll bar
that was previously attached to the flickable, but it is still not good
that the original scroll bar is created (and remains in memory). At the
same time, in other cases, this can still be a problem (such as the
created object is a controller and affects how the root object behaves).
- If there is a complex binding, such as `ScrollBar.vertical: condition
? scrollBar : null`, even if in the future the QML engine makes it
possible to disable creation of the original scroll bar (one proposal
was to add a new pragma), this binding may need to be repeated in where
the flickable is reused.
This is what I tried recently, and seemed to work fine:
```
Flickable {
id: root
// ...
property Component defaultScrollBar: Component {
ScrollBar { }
}
ScrollBar.vertical: {
if (condition && root.defaultScrollBar) {
return root.defaultScrollBar.createObject() // a parent is not
passed on purpose
}
return null
}
```
Both the default component and `ScrollBar.vertical` binding can be
changed in where the flickable is reused.
The important thing here is to rely on the JS engine's garbage
collection for the cases the component or condition changes after
completion. In that case a new object would be created, and the
previously created scroll bar would be no longer referred, so the engine
would destroy it. Also, `gc()` can be used to trigger purging stray
objects immediately, if there is a need.
Opinions are much appreciated.
Sincerely,
Fatih Uzunoğlu
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 4676 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20250411/5da3e04b/attachment.bin>
More information about the Interest
mailing list