[QML] Need advice on frontend architecture
-
This is a forum re-post of mailing-list thread [Interest] [QML] Need advice on frontend architecture. I'm asking the question here too to maximize reach; if good suggestions emerge from the mailing list, I will summarize them here once discussion stopped there.
Hi.
I recently joined a nascent QML project with the objective to bring it from the "working prototype" stage to something maintainable and efficient.
Previously, my last GUI work was on a web application using React + Flux, which I loved for the mental simplicity and testability their functional model brings (i.e: update the state, be confident that {1. the view is updated, 2. with good performance regardless of the state mutation complexity / number of bindings}).
Now, back to QML, looking at the documentation, examples, and a few blog posts,
-
I find a good overview of QML language constructs
-
... as well as tons of simple, mostly stateless widget examples
, but:
-
I have yet to encounter frontend architecture recommendations (like Flux)
-
I often stumble on QML constructs that push me into one-component-directly-mutating-another corners. Drinking the React kool-aid made me very wary of those, and I'd now actively avoiding them because they can quickly lead to spaghetti. For example, QML states, and direct mutations using
parent
,root
, or accessing byid
.
So, as you can expect, I'm trying to bring a Flux-ish approach to our QML app, by creating central data stores encapsulating {a. my application state as pure data, b. functions to manipulate the state}, and making my QML components depend on this pure data.
But so far it feels like I'm swimming against the tide, plus:
-
I have little idea how performance will evolve down the road.
-
Contrarily to the web application mentioned in the introduction, I also have to mix my JS state with C++ classes instantiated in my QML, also bringing their own state, which I use too in QML.
-
My store-observing logic implies regularly using
onXyzChanged
signal handlers (e.g. to re-generate a ListModel when the source Array changes), which means bring Data Store attributexyz
to the local QML component scope, which isn't feasible with current-scope-limited property aliases, so I'm using ordinary property references (property var cheeses: dataStoreInventory.cheeses;
), which "allocates a new, unique storage space for the property", effectively doubling the memory usage of my state, with unknown memory leaking behavior. -
I'm reading lots of very affirmative, but sometimes old, and often poorly researched articles encouraging QML developers to avoid JS and do all the logic in C++, save for basic widget arithmetic. As a web developer, the productivity benefits of JS are obvious to me (plus the library availability, when libraries are content with the exotic JS environment provided by QML, but that's another question), but these claims are starting to make me wary of too much JS in my QML app. Or maybe these cautionary tales are just instances of good tools badly used yielding bad results? Anyway I'm wondering how much JS is reasonable in a long-running QML app with serious performance expectations (calculations and heavy 2d/3d in C++, QML gui)
As you can guess, I'm lost in all this. Do you have battlefield-tested advice/links to structure QML apps? Thanks for your help.
-