[Interest] [QML] Need advice on frontend architecture

Ronan Jouchet ronan.jouchet at cadensimaging.com
Wed Nov 18 17:14:34 CET 2015


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 [1] + 
Flux [2], 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 [3], 
and direct mutations using `parent`, `root`, or accessing by id.

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 attribute `xyz` to the local QML 
component scope, which isn't feasible with a current-scope-limited 
aliases [4], 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.

[1] https://facebook.github.io/react/
[2] https://facebook.github.io/flux/
[3] http://doc.qt.io/qt-5/qtquick-statesanimations-states.html
[4] 
http://doc.qt.io/qt-5/qtqml-syntax-objectattributes.html#property-aliases

-- 
Ronan



More information about the Interest mailing list