Qt Commercial Support Weekly #18: Using QVariantMap to Emulate Passing by Reference and Pointer in QML
When you are combining QML with C++ code it is possible to call a function in your class from the QML in order to do some specific handling that you don't want to do in the QML code. This function can be a slot or it can be another member that has been marked with Q_INVOKABLE. This post won't go into detail on how to get that setup but it will focus on how to get around the fact that you cannot pass by reference or pointer from QML to C++. Let's say that you have a function like this:
Q_INVOKABLE void testFunction(int &a, int &b)
a += 5;
b += 10;
If this is called from within C++ then it will work fine, however, if you want to call this function from QML like this:
var a = 1;
var b = 1;
Then it will not be able to run the QML code because it cannot match up with the reference to the int variables in the testFunction function. If they were just passed as plain integers, then it would work, but then we would not be able to get access to the modified variables as the referencing benefit would have been lost.
So, in order to deal with this particular scenario we need to use QVariantMap to take care of this setup. We have two options here, we can either modify the existing function or we can add one that would add as a wrapper for QML, if we need the original one to stay intact for existing C++ related functionality. In this case I will just modify the existing one. In order to be able to enable QML to at least be able to call this function we need to change the parameters to be plain integers and not references to them. In addition, we need to return a QVariantMap from this function so the function should look like this:
Q_INVOKABLE QVariantMap testFunction(int a, int b)
Now, all that is left to do is to take the existing functionality and extend it so that it puts the results into a QVariantMap and returns it. When we insert into the QVariantMap we need to give a name for the variables being stored in it so that we can easily access them on the QML side. For convience, I will just use aInt and bInt. So, we need to do something like:
a += 5;
b += 10;
And that is all there is to it on the C++ side of things. The only thing left to do is to fix up the QML side of the application. Since we know that we will be getting the results in a QVariantMap, then we just need to put that in a variable and then print the results from that, so this is luckily fairly straightforward to do and can be done like:
var a = 1;
var b = 1;
var resultMap = externalClass.testFunction(a, b);
In the print statements we refer to the names we gave the variables, this makes it easy to access any given variable inside the QVariantMap. There you have it - a simple way to get around the fact that you cannot pass by reference or pointer, and if you go with the route of wrapping around the existing function then you can easily have the best of both worlds.
Until next time, happy coding :)
Subscribe to our newsletter
Try Qt 5.12 LTS Now!
Download the latest release here: www.qt.io/download.
Qt 5.12 was developed with a strong focus on quality and is a long-term-supported (LTS) release that will be supported for 3 years.
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.
Näytä tämä julkaisu Instagramissa.
Want to build something for tomorrow, join #QtPeople today! We have loads of cool jobs you don’t want to miss! http://qt.io/careers #builtwithQt #software #developers #coding #framework #tool #tooling #C++ #QML #engineers #sales #tech #technology #UI #UX #CX #Qt #Qtdev #global #openpositions #careers #job
Henkilön Qt (@theqtcompany) jakama julkaisu