[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