2

我正在用 QT 和 QML 开发一个应用程序来访问一些 XML 数据并显示结果。

XML 是从 C++ 下载/解析的,并且工作正常。我有一个用于显示自定义布局的 QML 应用程序,它也可以正常工作。

为了使应用程序看起来更精致,我在 C++ 端完成初始下载/解析时显示了一个初始“启动屏幕”,我在主 QML 视图中创建了一个属性来表示当前应用程序“状态”,以便我可以交换数据准备好后到正确的屏幕。

主.qml

Item
{
   id: mainScreen
   width: 800; height: 600;   
   property int activeState: 0       // This controls what screen is displayed

   Item 
   {
       // screen layout .. removed .. 
   }
}

C++ 代码由 QT creator 应用程序向导生成,并基于基本QmlApplicationViewer类。

我已经阅读(并重新阅读)了在线 QT 文档,据推测我要访问的各个属性所要做的mainScreen就是调用findChild<QObject *>应用程序查看器的方法rootContext()以返回QObject指向mainScreen实例的指针,然后setProperty像这样调用该方法.

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");

其中在ROOT_CONTEXT别处定义为

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);
}

void QmlApplicationViewer::createMyApplication(void)在设置主 QML 文件后调用,即

QmlApplicationViewer viewer;

viewer.setMainQmlFile(QLatin1String("main.qml"));
viewer.showExpanded();
viewer.createMyApplication();

但...

我遇到的问题是返回的值findChild<QObject *>("mainScreen");始终为 NULL。我尝试使用以下代码枚举我的 QML 文件中的对象层次结构

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();
}

我得到了一个大约 120 个项目的列表,但它们的名称都有一个空白字符串 ("")。

回顾 QT 文档,所有示例似乎都建议手动创建各个部分(即创建 和 的实例QDeclarativeEngineQDeclarativeComponent并将QDeclarativeItem它们链接在一起,而不是使用QApplicationViewer此博客条目http://xizhizhu.blogspot 中显示的类。 co.uk/2010/10/hybrid-application-using-qml-and-qt-c.html,但我更愿意坚持使用我已经编写的代码。

任何人都可以请帮助并建议我哪里出错或指出我可以找到一个“简单”示例的方向,该示例能够从 C++ 更改 QML 文件中项目的属性。

提前很多(很多)感谢。

乔恩...

4

2 回答 2

3

更新

以下代码

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();
}

工作并转储对象列表,当我在我的 QML 文件中使用 objectName: 属性时,如上所述,我可以在我的应用程序中看到(并访问)ROOT 项的子项。

然而,我似乎无法做的是实际上访问 ACTUAL ROOT 项目并设置它的属性 - 他们在典型的面部手掌时刻让我恍然大悟,我已经参考了根对象!这是已经存储在 ROOT_OBJECT 变量中的值 * sheesh *

所以总结...

上述所有代码都有效——要在主视图中实际查找和调整 CHILD 的属性,请记住设置objectName:,如果要实际更改根项中的属性——只需使用函数返回的值即可QDeclaritiveView::rootObject()

再次感谢IvanFel为我指明了正确的方向,希望这会在某个时候出现在搜索中并帮助其他人,就像过去很多 stackOverflow 条目帮助我一样。

8-)

于 2012-11-08T09:49:39.330 回答
2

Main.qml 应该是

Item
{
   id: mainScreen
   objectName: "mainScreen"
   width: 800; height: 600;   
   property int activeState: 0       // This controls what screen is displayed

   Item 
   {
       // screen layout .. removed .. 
   }
}

您缺少 objectName:“mainScreen”,这就是 findChild<>() 找到它的孩子的方式。

于 2012-11-07T18:12:52.077 回答