如何从C++访问QML ListView代理项?

3
Listview中,我使用“delegate”弹出了100多个项目,假设listview已经显示了填充值。 现在我想从C ++中提取已经显示的QML列表视图中的值。如何实现这一点? 注意: 我无法直接访问datamodel,因为我正在使用 hidden 变量过滤代理。
        /*This is not working code, Please note,
        delegate will not display all model data.*/
        ListView
        {
        id:"listview"
           model:datamodel
           delegate:{
                      if(!hidden)
                      {
                        Text{        
                        text:value
                      }
                    }

        }


 //Can I access by using given approach?
 QObject * object =   m_qmlengine->rootObjects().at(0)->findChild<QObject* >("listview");

//Find objects
const QListObject& lists = object->children();

//0 to count maximum
//read the first property
QVarient value =  QQmlProperty::read(lists[0],"text");

你应该至少从一个可运行的代码开始。此外,你应该尽量减少从C++到QML的访问,特别是在这种情况下。如果你想在C++端使用模型数据,请使用C++模型。 - dtech
我正在进行自动化测试,无法使用模型数据进行验证,因此在qml中显示列表视图后,我需要从qml中提取数据到C++并进行验证。 - Ashif
我认为它不会像你期望的那样工作,你最好在 QML 中迭代这个列表视图,并通过将文本传递到插槽函数来将其发送到 C++。 - dtech
由于我正在进行自动化测试,无法编辑/触摸qml,因此我使用qml插件,以便应用程序不会受到自动化测试代码的干扰。 - Ashif
2
在QML中进行您的QML测试:http://doc.qt.io/qt-5/qtquick-qtquicktest.html - dtech
我可以使用QML进行QML测试,我已经使用了QML插件来完成。上面的评论很有用。 - Ashif
1个回答

5

您可以使用 objectName 属性在 QML 中搜索特定项。让我们看一个简单的 QML 文件:

//main.qml
Window {
    width: 1024; height: 768; visible: true
    Rectangle {
        objectName: "testingItem"
        width: 200; height: 40; color: "green"
    }
}

在C++中假设engine是加载main.qml的QQmlApplicationEngine,我们可以通过从QML根组件搜索QObject树并使用QObject::findChild轻松找到testingItem

//C++
void printTestingItemColor()
{
    auto rootObj = engine.rootObjects().at(0); //assume main.qml is loaded
    auto testingItem = rootObj->findChild<QQuickItem *>("testingItem");
    qDebug() << testingItem->property("color");
}

然而,这种方法不能找到QML中的所有项,因为某些项可能没有QObject父项。例如,在ListViewRepeater中的代理项:
ListView {
    objectName: "view"
    width: 200; height: 80
    model: ListModel { ListElement { colorRole: "green" } }
    delegate: Rectangle {
        objectName: "testingItem" //printTestingItemColor() cannot find this!!
        width: 50; height: 50
        color: colorRole
    }
}

对于ListView中的委托,我们需要搜索可视子项而不是对象子项。 ListView 委托被设置为ListView的contentItem的父级。因此,在C++中,我们必须先搜索ListView(使用QObject::findChild),然后使用QQuickItem::childItems搜索contentItem中的委托:
//C++
void UIControl::printTestingItemColorInListView()
{
    auto view = m_rootObj->findChild<QQuickItem *>("view");
    auto contentItem = view->property("contentItem").value<QQuickItem *>();
    auto contentItemChildren = contentItem->childItems();
    for (auto childItem: contentItemChildren )
    {
        if (childItem->objectName() == "testingItem")
            qDebug() << childItem->property("color");
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接