
Ask HN: Good architecture for C++ / QML projects? - laurent123456
I&#x27;ve been reading about this for some time but can&#x27;t find any good technique. Basically I&#x27;m wondering how do people architecture C++ &#x2F; QML projects and in particular the communication between the C++ and QML side.<p>In general I can get things working but after a while it becomes a mess of signals and slots, some signals being queued other immediate, which makes it very difficult to reason about. Basically it&#x27;s not clean like a React&#x2F;Redux architecture or MVC on the server-side can be.<p>I did stumble across &quot;quickflux&quot; but that seems a bit of a complicated hack, while I&#x27;d rather go for something simpler and more native to C++&#x2F;QML.<p>Any suggestion?
======
usernam
Do you actually need QML? What's wrong with "native" widgets?

I ask because I use Qt and c++ professionally, and have no use of QML. I could
elaborate, but I'm more interested in why exactly you'd go for QML first.

~~~
laurent123456
In fact I'd rather use native QWidgets as I find it much easier to work with,
however as I understand Qt is now increasingly giving priority to QML so I'm
trying to use it for this new project.

Also this is a mobile app and it seems Qt Quick is designed for this. I'm
curious actually are the apps that you develop meant for mobile devices as
well? And if so, how does the QWidgets work on them?

~~~
usernam
No, I don't develop for mobile, so I cannot answer there. Exclusively desktop.

I know Qt5 is pushing towards QML, but QWidgets aren't going away. In fact, I
would consider it to be a _big_ mistake to use QML on desktop. It's much
slower and doesn't really save the developer anything: pushing state to the JS
layer doesn't you any good if you need to keep it sync with the lower layer as
well. It's an extra indirection. It also looks completely out of place in all
platforms.

QML _might_ be partially useful for drawing on GL surfaces, but again the
performance hit will be a huge setback. We use different widget kits for
drawing on GL. Since QML and QWidgets are different anyway, there's no reason
to stick to it.

Also, QML widgets are improving, but they're all still qualitatively inferior
from an user/usage perspective.

------
once-in-a-while
I wonder why people want to use/abuse signals and slots in QML, when it's
perfectly possible to just use good old plain functions in a language binding,
like it is done here (for ECL/Common Lisp):

[https://gitlab.com/eql/EQL5/blob/master/examples/M-modules/q...](https://gitlab.com/eql/EQL5/blob/master/examples/M-modules/quick/qml-
lisp/qml/example.qml)

------
guruz
QML evolved from binding Qt C++ objects into QtScript (JavaScript). If your
QObject has Q_PROPERTY, signals, slots etc. you can access it from QML too.

Did you see [https://doc.qt.io/qt-5/qtquick-modelviewsdata-
cppmodels.html](https://doc.qt.io/qt-5/qtquick-modelviewsdata-cppmodels.html)
already?

Shamless plug: You can also ping us at info@woboq.com and we might be able to
help with architecture/development of Qt applications.

~~~
zerr
Btw, do you get enough leads from your website?

------
bwoj
On my last project we started an effort to redo our QWidget implemented UI
with QML. The QML version was really slow, we actually ended up buying a
commercial license to get access to a QML compiler just to speed things up.
And that was for desktop, I'd expect it to be even worse for mobile.
Integrating the QML components with the QWidget components was especially
buggy. For a 100% QML project this would be less of a problem.

Interfacing C++ to QML is clearly not a priority in the design of the whole
system. You can do slots/signals or you can register C++ objects into the QML
namespace. Something along the lines of this tutorial:
[http://doc.qt.io/qt-5/qtqml-tutorials-extending-qml-
example....](http://doc.qt.io/qt-5/qtqml-tutorials-extending-qml-example.html)

Overall, I find the whole QML environment to be disappointing and I don't plan
to use it again until it becomes more mature.

~~~
laurent123456
I've ran a few QML tests on Android (reading/writing to/from an SQLite DB,
displaying the results in a list, synching with a web API) and it seems
reasonably fast. Did you identify something in particular that was making the
app slow? Or was it just that the app was particularly complex?

~~~
bwoj
To my recollection, the worst performer was parsing all of the QML at startup.
This did not impact us at first, but as we grew the QML portion it went from a
noticeable delay at startup to an unacceptable delay. It was something on the
order of 10-30 seconds (on rather high-powered workstations to boot) to parse
all of the QML files for what amounted to less than a dozen UI screens.

------
fundamental
I personally liked the idea of using QML, but the C++/QML interface made using
it difficult. In the end I end up making another toolkit which consumed QML-
like files and executed them using the mruby VM which has a much simpler C
interface.

------
iheartmemcache
So this is where I'd start[0].

Their site has amazing documentation. I personally found Qt even in the KDE2
days _miles_ better than React/Redux and non-Smalltalk MVC's. Since then it's
only gotten better. Check out the examples here[1], the diving in section
here[2], the book here[3], Stackoverflow has an overview of the whole system
here[4].

You emit signals. Slots consume them. QObject::connect links the two. Queues
are just queues in the traditional MQ sense. You don't use them in for, say,
local GUI controls since it's generally a 1-1 unidirectional link (and if it's
bi-directional, although I rarely need to do this, just ::connect(
a,b,SLOT(),SIGNAL() ) then ::connect( b,a,SLOT(),SIGNAL() ). If you're still
having problems read this[5]. If you have issues, that blog also has a
preceding page which has a comprehensive analysis of the underpinnings of the
entire slot/signal system in QT. If you _still_ have problems, get on IRC and
someone will give you a hand. If you're having a major issue, contact me. If
it's a quicky I'll lend a hand, if not I know a few absolutely spectacular HN
engineers who I'd recommend in a heartbeat.

I'd be real curious as to what's you consider 'messy' about signals/slots is
you're having re: slots/signals (I guess since I've used Moose's MOP with Perl
5 and CL they sort of came naturally to me). I have no affiliation with
Trolltech/QT/Nokia/whoever-owns-whatever-now at all; I just think C++ is real
easy to mess up, libraries are even easier and they did a way-above-average
job with their code-base (not to mention, documentation, ecosystem, etc).

The setup you want to use for cross-platform is Qt5.x + QML 2.x + QtQuick 2.x
(aka QtQuickControls 2 in newer versions). There's licensing issues on some of
the fancy-schmancy widgets but most of the things follow LGPL, so just
dynamically link, follow the rules, and you won't get sued. If you're working
on a legacy codebase (gcc2.95.3 hollaaaaa), don't try to force new-style QT
into an old project, or your experience will be similar to @bwoj. 5.6(or there
abouts) and up is where QML started to shine.

N.b. you don't have to use QTcreator. I find it satisfactory but that just
might be years of Stockholm Syndrome. Most people coming from the C++/MFC (or
C++/WTL/ATL/COM/WinAPI world) are more comfortable with Visual Studio. No
problem, the 'standard' procedure is just to do what you would do with any
.sln and split GUI into another project.

\----

[0] [https://www.qt.io/qt-essentials-qt-quick-for-c-
developers/](https://www.qt.io/qt-essentials-qt-quick-for-c-developers/)

[1] [http://doc.qt.io/qt-5/qtquick-
codesamples.html](http://doc.qt.io/qt-5/qtquick-codesamples.html)

[2]
[http://doc.qt.io/qt-5/qmlapplications.html](http://doc.qt.io/qt-5/qmlapplications.html)

[3]
[https://qmlbook.github.io/assets/qt5_cadaques.pdf](https://qmlbook.github.io/assets/qt5_cadaques.pdf)

[4] [http://stackoverflow.com/a/19837895](http://stackoverflow.com/a/19837895)

[5] [https://woboq.com/blog/how-qt-signals-slots-work-
part2-qt5.h...](https://woboq.com/blog/how-qt-signals-slots-work-
part2-qt5.html)

~~~
laurent123456
Thanks a lot for the explanation and the links, I'm going to go through all
this.

I think the signal/slot system of Qt is very well designed actually (I had no
problem with it in pure C++ applications), it's just my implementation while
using QML which ended up being messy. I also had to refactor some parts due to
Android not liking slots in one thread and signal emitter in another. Also it
seems signals were sent in a particular order on desktop and a different order
on Android. That's why I'm looking for a clean architecture which would allow
me to know and reason about what's happening in the application.

~~~
nottorp
[quote] I also had to refactor some parts due to Android not liking slots in
one thread and signal emitter in another. [/quote]

Ouch? Worry free passing of signals/slots between threads is a feature of
desktop Qt that I use and abuse all the time. I've even done a GUI-less daemon
that used QtCore and abused signals/slots to communicate between threads. You
mean it doesn't work on the mobile versions?

