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
Item
{
id: mainScreen
objectName: "mainScreen"
width: 800; height: 600;
property int activeState: 0 // This controls what screen is displayed
Item
{
// screen layout .. removed ..
}
}
You were missing the objectName: "mainScreen", that's how findChild<>() finds it's children.