I am invoking a QML function from C++. Issue is the QML function cannot update a QML element when invoked from C++. below is code:
In main.qml
:
import QtQuick 2.0
function myQmlFunction(msg) {
console.log("Got message:", msg)
textbox.text = msg
return "some return value"
}
Text {
id: textbox
text: "nothing"
}
In main.cpp
:
QQmlEngine engine;
QQmlComponent component(&engine, "MyItem.qml");
QObject *object = component.create();
QVariant returnedValue;
QVariant msg = "Hello from C++";
QMetaObject::invokeMethod(object, "myQmlFunction",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, msg));
qDebug() << "QML function returned:" << returnedValue.toString();
delete object;
The textbox element is just a regular text, and the text inside it remains "nothing", instead of the expected "Hello from C++".
Any ideas on how to solve this issue or in successfully passing arguments from C++ to QML?
Lé Code
Qml
I'll assume that the qml code given actually belongs to
MyItem.qml
instead ofmain.qml
.Your Qml file generated an compile-time error. Functions should be placed inside an object, like so
I'm not sure how you were able to compile your project without generating an error, but I'm guessing either
I'm sure you have a sufficient understanding about Qml so I'm not going to go deep into this.
C++
On the C++ side, I had to fiddle around with debug output to see what's wrong. Here's my
main.cpp
:Output
The output I received on a successful build, with a successful object creation was
I haven't yet checked whether the text changed in your Qml
textbox
. (Didn't bother to. It'll require more changes to the C++ code and this answer is already long enough. I was also confident that nothing'll go wrong, so ¯\_(ツ)_/¯).Lé Non-Code
What if I don't want to use a raw file path?
If you're meh about using a raw file path (e.g.
/Users/whoami/ugly/looking/path
) inYou can add this to your
.pro
file:and set
projectPath
toThis idea was borrowed from a forum thread.
Assumptions
Throughout my answer, I have assumed that your project hierarchy resembles
The essential thing is that you use your full path to your qml item. If you do find another to reference it (maybe using
QUrl
?) then do post a comment about it.Further Reading
Check out the details section of the
QQmlComponent
class andQQmlComponent::create
member function. Reading these led me to know which values to debug and what to look out for.