6
votes

I'm trying to do a simple task as changing a property (text: ) of some QML object from C++ yet I'm failing miserably. Any help appreciated.

I'm not getting any errors, the window shows up, just the text property doesn't change as (at least I think) it should. Is even anything I'm NOT doing wrong here?!!

What I was trying is this:

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQuickItem>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QString>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;


    QQmlComponent component(&engine, QUrl::fromLocalFile("main.qml"));
    QObject *object = component.create();

     engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    QString thisString = "Dr. Perry Cox";

    object->setProperty("text", thisString);  //<--- tried  instead of thisString putting "Dr. ..." but nope.
    delete object;



    return app.exec();
}

main.qml

import QtQuick 2.2
import QtQuick.Window 2.1

Window {
    visible: true
    width: 360
    height: 360

    MouseArea {
        anchors.fill: parent
        onClicked: {
            Qt.quit();
        }
    }

    Text {
        id: whot
        text: ""
        anchors.centerIn: parent
        font.pixelSize: 20
        color: "green"
    }
}
3
Thank you for the link Retired Ninja (like your name btw) but that's exactly where I started from, I did the example there and thought I'd try and change some other property like text (not just width and height). Maybe I'm a little bit retarded but I can't learn a (insert bad word here) from the documentation. - hekri
I figured in case you hadn't seen that it might help. The warning about manipulating objects deep in the tree from that link is probably the best part. What you're attempting to do probably isn't the best way to go about it. We used to do something like what was described in the docs and access child items by name, but assigning a unique name to a bunch of things is a pain. Generally now we just use bindings to properties provided by c++ or signals to keep the qml in sync and we're much happier. - Retired Ninja
So you mean I shall dig deeper in the documentation or is there any other source of information from where I could possible learn something? - hekri

3 Answers

6
votes

When you call QObject *object = component.create(); you get access to the root context, which is the Window component and its properties.

To get access to Text properties, you can create property alias like this:

Window {
    property alias text: whot.text
    ...
    Text {
        id: whot
        text: ""
        ...
    }
}

That will give you access to whot's text property from within the Window's context.

There is another slightly more round-about way. Assign objectName property instead of id (or both if you still need id) to whot:

Text {
    id: whot // <--- optional
    objectName: "whot" // <--- required
    text: ""
    ...
 }

Now you can do this in code:

QObject *whot = object->findChild<QObject*>("whot");
if (whot)
    whot->setProperty("text", thisString);

On a side note: I don't think you are supposed to delete the object until after calling app.exec(). Otherwise, it will ... well, be deleted. :)

0
votes
#include <QQmlContext>
#include <qquickview.h>
#include <qdir.h>

QQmlApplicationEngine engine;
QString root = QCoreApplication::applicationDirPath();
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
        return -1;
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow*>(topLevel);
window->setProperty("root", root);

for qml

ApplicationWindow  {
    property string root
    onRootChanged: {
        console.log("root : "+ root);
    }
}
0
votes

For QML properties you should use QQmlProperty instead:

QQmlProperty::write(whot, "text", thisString);