Using QML without JavaScript
-
- It is not type safe
- Our static code analysis tools won't cover it
- Our code coverage tools won't cover it
- It would require a totally different approach to (unit) testing
- Debugging works entirely different
- It does random stuff (ok, this one is a bit tongue-in-cheek)
I can see the use of a static language like QML, but I would like to keep anything dynamic in C++
-
So you want to use Qt Quick with its visual scenegraph in C++, not QML the language.
There's no official way to do that since most of the API is not accessible in C++, there's only QQuickItem.
You could take a lookt at https://github.com/uwerat/qskinny though.Or if you eventually want to use QML, you could use FrogLogic Squish for GUI testing and still use C++ for your business layer with all your existing test infrastructure.
-
@GrecKo Allow me to elaborate a bit.
I don't yet understand why JavaScript is mandatory to use. The way I understood the concept of QML/Qt Quick when it was introduced in 2010 was to have a clean separation between GUI and logic/data backend. Write the GUI in QML and write the backend in C++Now I have a visualization for the state of machinery. I have a virtual representation on the current state of the machine in a data layer. Any changes to the GUI must first be reflected in that data layer.
In the other direction, any interaction with the GUI must immediately reflect in the data layer, which will trigger the necessary commands to be sent to the machine.If I have this kind of coupling, how can the C++ backend/logic/data layer not be in full control of the GUI?
I can access the root item (QQuickItem) via QQuickView. I can get its children via childItems. I can set an item's state via setState. Via QObject introspection, I can enumerate and access all properties.
What exactly can I not do via C++ that I can do via JavaScript? -
I don't understand what you want.
It seems that you want to use QML without JavaScript. Do you have an example of how that would look like?
ApplicationWindow { Text { anchors.centerIn: parent color: "orange" text: CppBackend.foobarProperty } }
Is the above code acceptable to you?
If yes, what is not?
If no, what is? -
@GrecKo
I don't per se want to use QML, but I'm open to the idea.
What I need is a modern, well-performing and fully supported engine for user interfaces. So far, I used QWidgets for the basic/standard stuff and QGraphicsView for the heavy lifting and complex (2D) displays. The QWidget parts can (and probably will) stay, but I need something up-to-date and fully supported for the complex stuff.The way I see it, I can hardly evade QML, and it might bring some side benefits, so I'm ok with that. But including logic into the QML files via JavaScript sounds like it breaks the separation between UI and logic, and (as mentioned) opens a can of worms regarding development environment, code reuse, debugging, testing,etc.
-
@Asperamanca said in Using QML without JavaScript:
But including logic into the QML files via JavaScript
you keep your business logic in c++,
use js for ui logic/dynamic behavior -
@LeLev
It would help me to understand where you draw the line between business and UI logic. Can you give a couple of examples?All of you: Please don't get me wrong.
I'm not against JavaScript per se. I just don't see it as a good choice for my use case. I have to think this through a bit more, but if JavaScript is an essential, non-negotiable part of QML, it may be the reason not to adopt QML for a large project.This is why I am testing the statement that QML without JavaScript doesn't work.
I can see that you can do a lot with standard QML items from C++. I can read and change any of the 78 properties (in 5.12) for the QML text component, for example. I can attach to all its signals. I can invoke all it's methods.
What more can I do with JavaScript?
-
@Asperamanca
lets imagine we need HMI application for a CNC machine.So your program needs to connect to a CNC machine using a protocol, lets say OPC UA.
It also need to read and show information from PLC of your CNC machine, say the machine motor speed.here you need a qml Gui for the user interface and you need C++ for the buisness logic (opcua connexion / read / write data)
// c++ here you do all the connetion / read / write buisness logic class MachineBackend : public QObject { Q_OBJECT public: Q_PROPERTY(float speed READ speed WRITE setSpeed NOTIFY speedChanged) /// make your class object reachable in qml MachineBackend m; QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("machine",&m); ///
//qml / js Text{ id : speedView text : machine.speed color : speed > 80 ? "red" : "green" //<< ui logic ,handy js ! this will refresh when speed changes + its independent, you can change you backend (c++) and decide now you use MQTT protocol, this will still work }
--
in this example you could use js for the opc ua or the mqtt (backend) but its bad idea
also you could make the text dynamic behavior(front end) from C++ dut its bad idea -
@LeLev Thanks for the detailed example.
That approach fails for me for two reasons:- Due to the size of code to migrate, there are going to be several versions where C++ UI and QML UI will exist side by side. Yet the UI logic needs to be consistent between both kinds of views
- The color of a LED can affect important decisions by the operator, it needs to work reliably. What kind of static code analysis, debugging capabilities and ability to write automated test drivers (no, not high-level GUI test, but module-level logic tests) exist for this embedded JavaScript code?
Maybe I am wrong, but all of JavaScript I have seen so far is that the language has its strengths in being quick to implement something, and failing silently. After all, what does it matter in a web page whether the "pressed" color of a button is updated correctly, as long as the button works? And even if the button does not work, the site administrator can quickly identify the problem by looking at site statistics (because no-one does a certain operation, which is unusual)
-
@Asperamanca said in Using QML without JavaScript:
What I need is a modern, well-performing and fully supported engine for user interfaces.
I'd say that Qt Quick fits this description. It takes advantage of modern graphics hardware; Qt Widgets and the Graphics View Framework do not.
Note that Qt Quick != QML. Qt Quick is the graphical engine while QML is the language designed for writing Qt Quick code. You can think of QML as a superset of JavaScript.
There is a chance that in Qt 6, a lot more of Qt Quick will be exposed to the C++ side. For now though, you'll need to write QML to meaningfully use Qt Quick.
including logic into the QML files via JavaScript sounds like it breaks the separation between UI and logic
While the JavaScript can be used to implement business logic in the *.qml files, you don't have to do that (and oftentimes you shouldn't).
If you want to force yourself to keep business logic out of your *.qml files, then use the UI Forms that @LeLev spoke about. The Qt Quick Designer will forbid you from accidentally introducing non-trivial logic into your *.ui.qml files.
Is it possible to entirely disable JavaScript in QML, or even remove the JavaScript engine from a Qt build?
Technically, no.
QQmlEngine
inheritsQJSEngine
. In other words, the QML engine is a JavaScript engine by definition.In practice, it is possible to write QML while avoiding "non-trivial" JavaScript.
@LeLev Thanks for the detailed example.
That approach fails for me for two reasons:
...Again, you don't have to do things the way that @LeLev demonstrated. The option is there for those who want to use it, but you are not forced to use it. By all means, bind the LED colour to a C++-defined object -- that is valid QML too!
-
@JKSH
Thank you, that cleared a lot up!I don't mind that the possibility exist to use JavaScript for logic - and I might even use it in some cases. It just didn't make sense to translate logic that already exists in C++, and already is separate from the UI. At the beginning of the discussion, I had the feeling that JavaScript is mandatory even for non-trivial logic stuff, and that scared me...
-
@Asperamanca https://www.qt.io/blog/2019/08/07/technical-vision-qt-6 see next generation qml