Reputation: 38
I'm working on a C++ Qt project that will eventually communicate with the serial port. One part of this is accessing QML objects in the C++ portion. I have code that can set properties of the QML, but accessing those features that are methods now has me stumped. View the following code:
object = view.rootObject();
rect = object->findChild<QObject *>("box");
rect->setProperty("color", "red"); // Verifies the object tree is accessible
viewer = object->findChild<QObject *>("viewer"); // Access the viewer text box
viewer->append("dummy text"); // OOPS! This doesn't compile!!!
Now, the type as a method setProperty(..), but how do you access methods of an object. "viewer" is a TextArea and I want to first do a selectAll(), then a cut() to clear the box.
The question here is how is this coded? Thanks all.
Upvotes: 0
Views: 8461
Reputation: 8698
The author's QML part may expose alias property to operate with desired text field content:
import QtQuick 2.0
import QtQuick.Controls 1.2
Item {
property alias viewerText: viewer.text // added
width: 350
height: 450
TextArea {
id: viewer
x: 8
y: 8
width: 223
height: 415
text: "text"
font.pixelSize: 12
objectName: "viewer"
}
Button {
id: open
x: 251
y: 8
text: "Open"
}
}
And then the author's C++ part can easily do:
auto* object = view.rootObject();
viewer = object->findChild<QObject *>("viewer");
viewer->setProperty("viewerText", "dummy text"); // using the new property added
Upvotes: 2
Reputation: 38
Using the posted answer here using the invoke method, here's the solution that works:
// C++ Code to call function reset()
QMetaObject::invokeMethod(object, "reset");
// QML code to select all text the delete it
function reset() {
viewer.selectAll()
viewer.cut()
}
Upvotes: 0
Reputation: 49289
Of course it would not compile, QObject
doesn't have an append()
method.
If it is a C++ function, you will have to qobject_cast
to the appropriate type that has it. This however is not always readily available for many of the stock QML types that are implemented in C++, and as C++ types they are not part of the public API and not generally intended for direct use by an end user.
If it is a JS function, you will have to use QMetaObject::invokeMethod
. That will also work for C++ functions for which meta data has been generated. Which is also how setProperty()
works, whereas setColor()
would not work with a QObject*
much like append()
doesn't.
Last but not least, there is absolutely no good reason for you to be doing those kinds of things from C++. Using QML objects from C++ is poor design and an anti-pattern. You will only develop bad habits trying to do that. Such interactions must be limited to a clearly defined interface using signals, slots and properties. Generally speaking, it is OK for QML to reach into C++, because that only happens through an exposed interface, but the opposite way, even if possible, should not utilized.
Think of it like this - a car uses the engine, the engine doesn't use the car. And the engine control is interfaced through the starter key and the gas pedal, it is not used directly. The C++ stuff should be reserved to the application engine - the high performance or efficiency core logic, or the back-end, whereas the QML part is for the GUI/front-end.
Upvotes: 4