10

Consider the case of a simple GUI displaying the output of rather elaborate calculation.

Now I would like to write a nice, custom GUI using QML.
I would also like to write my background app in QT C++.

I'm sitting in front of the QT documentation and wonder if I
1) should write a QML application and somehow embed my C++ classes in it (which is absolutely possible) or if I
2) should write a C++ application and somehow embed the QML GUI in it and modify QML properties from my classes (which is again possible)

I already wrote everything in C++ using QT Widgets for the GUI. I only want to move the GUI to QML and keep the C++ classes even though I am willing to rewrite the interface to the GUI.

Possible anser:

The marked solution below suggested keeping the C++ classes and interface the GUI exclusively through SIGNALS and SLOTS. So basically I ended up with a main.cpp that instantiates my main working class and displays the QML GUI like this:

QQuickView viewer;
viewer.setSource(QUrl("./qml/main.qml"));
viewer.show();

then I added myClass and got me an object to do the connections:

MyClass myClass;
QQuickItem* item = viewer.rootObject();
QObject::connect(item, SIGNAL(buttonClicked()), &myClass, SLOT(mySlot()));
QObject::connect(&myClass, SIGNAL(mySignal(QVariant)), item, SLOT(updateGUI(QVariant)));

When implementing the slots and signals in the C++ classes you must use QVariant objects to transfer the data. The QML file then implements SIGNALS e.g. for clicked buttons and SLOTS to receive data to display.

This is exactly what I was hoping for. The only change to my non GUI code was to do all the interactions via SIGNALS and SLOTS. Now I can even use both GUIs (QML / Widgets) for my application.

HWende
  • 1,705
  • 4
  • 18
  • 30

2 Answers2

8

Just write your core logic in C++, interface it with signals and slots, and you can use the same component with widgets and also with QML.

It is not rocket science, C++ logic allows usage with C++ and QML, JS logic - only QML. C++ and the Qt API is the more sound solution, because from JS you don't really have access to that much functionality of the Qt APIs, only a few methods are "ported" into the QML world. But all the high performance data containers and the execution performance itself is in C++.

If you only need to display results and console is not good enough, I'd rather keep to QtWidgets, because adding the declarative module slows compilation down significantly. The widget module is standalone now, so you are adding "extra" module even with QtWidgets (in Qt4 it was part of QtGui) but it is lighter. After you use widgets for prototyping your core logic, you can then implement a QML interface and just hook that up to the existing signals/slots/properties and bindings using them.

And no, you don't embed QML in C++ classes, it is the other way around, C++ is the more low-level layer, which is used to create QML components. As for the actual instantiation, you can go both ways - if you register a QObject based class to the QML engine, you can instantiate it in QML. Or you could instantiate the class in C++ and only make it available in the QML context - it doesn't really matter. If you need a single object, you better instantiate it in C++ in the main() function and make it available in the QML context, if it is components you intend to instantiate a lot - then create a QML component.

You could prototype the core logic with JS in QML and later port it to C++ if you want too. It looks like twice the effort, but if you make your bed right it is actually a productivity increase, because prototyping is that much faster in QML, catching errors is much safer and informative, and if you make your API well, porting the JS code to C++ is usually a minor nuisance - replace some vars with concrete types, replace some . with -> and stuff like that.

Any "elaborate calculation" you really WANT to ultimately do in C++. Every time the calculation is completed, you can simply emit it as a signal, and automatically display the result to whatever slot the signal is connected, be that in a widget or in QML, or even both at the same time.

dtech
  • 47,916
  • 17
  • 112
  • 190
  • Looks as you are right. I figured out how to do it in a small demo and it exactly fits my need. The information exchange with signals (e.g. from GUI interactions) and slots is easy and I like that I can "plug" the background to different GUIs this way. The QML file provides a few slots to receive everything to display and that's it. Thanks! – HWende Aug 13 '13 at 10:30
  • @HWende - you are welcome, see my last edit regarding the actual instantiation of the C++ class. See this answer if you need help with the instantiation and registration of C++ classes to QML: http://stackoverflow.com/questions/16002310/qml-how-to-draw-multiple-rectangulars-in-random-places/16004056#16004056 – dtech Aug 13 '13 at 10:36
0

This is very opinion based. No 'true' answer possible. For me it is 'easier' to write in QML and 'extend' qml with Qt plugins. That's because I did a big project this way. Others might have other experiences and might because of that like a different approach. None of our 'life stories' could help you much.

Greenflow
  • 3,935
  • 2
  • 17
  • 28
  • It is very likely that one method is more easily accomplished when I have no experience in both ways. One method is probably more "beginner friendly" and someone who knows both methods might know which one. Let's give it a try! – HWende Aug 13 '13 at 09:38
  • It is not opinion based, it is experience, logic and reason based. One of the options is clearly counter productive and a bad approach, the other is the good, recommended practice. -1 for labeling it with "no true answer possible"... – dtech Aug 13 '13 at 10:03
  • If you say so. My opinion: Nonsense. Every project is different. Every gui is different. To explain here when one approach is better than the other could fill books. Do you have a large and complicated user interface? Only a few standard controls? Which approach is the right one must be decided new for every project. It depends not even only on pure technical reasons, but also on the technical experience of your team. Are they experienced more in C++ or in qml? Do they have time to get into new concepts? – Greenflow Aug 13 '13 at 10:15
  • I have time for a technically-grounded answer to a well defined question. And to point out a wrong one. I don't have time for discussing imaginary could-have-been-s - none of the dilemmas you describe applies to the current context. – dtech Aug 13 '13 at 10:22