Joe Voytovich
Joe Voytovich

Reputation: 38

Accessing Qt / QML objects with C++

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

Answers (3)

Alexander V
Alexander V

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

Joe Voytovich
Joe Voytovich

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

dtech
dtech

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

Related Questions