I am developing an application in QT and QML to access some XML data and display the results.
The XML is downloaded / parsed from C++ and this works fine.
I have a QML application designed to display the custom layout and that also works fine.
To make the app look more polished I have an initial “splash screen” that’s displayed whilst the C++ side completes the initial download / parse, I have created a property inside the main QML view to represent the current application “state” so I can swap to the correct screen when the data is ready.
Main.qml
Item
{
id: mainScreen
width: 800; height: 600;
property int activeState: 0 // This controls what screen is displayed
Item
{
// screen layout .. removed ..
}
}
The C++ code is generated by the QT creator app wizard and is based around the basic QmlApplicationViewer class.
I’ve read (and re-read) the online QT docs and supposedly all I have to do to access the individual properties of mainScreen is to call the findChild<QObject *> method of the application viewers rootContext() to return a QObject pointer to the mainScreen instance and then call the setProperty method like so.
QObject *mainView = ROOT_CONTEXT->findChild<QObject *>("mainScreen");
qDebug("mainView = %08X",(uint)mainView);
if(mainView)
{
mainView->setProperty("activeState",1);
}
else
qDebug("Unable to find the mainScreen QML object");
Where ROOT_CONTEXT is defined elsewhere as
QDeclarativeContext *ROOT_CONTEXT;
QDeclarativeEngine *ROOT_ENGINE;
QGraphicsObject *ROOT_OBJECT;
void QmlApplicationViewer::createMyApplication(void)
{
ROOT_CONTEXT = this->rootContext();
ROOT_OBJECT = this->rootObject();
ROOT_ENGINE = this->engine();
pMyApplication = new MyApplication(this);
}
and void QmlApplicationViewer::createMyApplication(void) is called after the main QML file has been setup ie
QmlApplicationViewer viewer;
viewer.setMainQmlFile(QLatin1String("main.qml"));
viewer.showExpanded();
viewer.createMyApplication();
BUT…
The problem I’m running into is that that the value returned from findChild<QObject *>("mainScreen"); is always NULL. I’ve tried enumerating through the hierarchy of objects in my QML file using the following code
QList<QObject*> list = ROOT_OBJECT->findChildren<QObject*>();
qDebug("list = %d",list.count());
int i;
for(i=0;i<list.count();i++)
{
QObject *obj = list[i];
qDebug() << "Object" << i << obj->objectName();
}
and I get a list of ~120 items but they all have a blank string (“”) for their name.
Looking back at the QT docs all the examples seem to suggest creating the individual parts by hand (ie creating an instance of QDeclarativeEngine, QDeclarativeComponent and QDeclarativeItem) and linking them together instead of using the QApplicationViewer class as shown on this blog entry http://xizhizhu.blogspot.co.uk/2010/10/hybrid-application-using-qml-and-qt-c.html, but I’d much rather stick with the code I’ve already written.
Can anyone please help and suggest where I’m going wrong or point me in the direction where I can find a “simple” example of being able to change a property of an Item in a QML file from C++.
Many (many) thanks in advance.
Jon…
Main.qml should be
You were missing the objectName: “mainScreen”, that’s how findChild<>() finds it’s children.