如何从 C++ 访问 QML ListView 委托项?

Ash*_*hif 3 qt qml qt5 qtquick2 qtquickcontrols

Listview中,我使用“ delegate ”弹出了 100 个项目,假设 listview 已经显示了填充值。现在我想从 C++ 中提取 QML 列表视图中已显示的值。如何实现这一目标?注意: 我无法直接访问数据模型,因为我正在使用隐藏变量在委托中进行过滤

        /*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");
Run Code Online (Sandbox Code Playgroud)

mcc*_*chu 5

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

//main.qml
Window {
    width: 1024; height: 768; visible: true
    Rectangle {
        objectName: "testingItem"
        width: 200; height: 40; color: "green"
    }
}
Run Code Online (Sandbox Code Playgroud)

在 C++ 中,假设engineQQmlApplicationEngine加载 main.qml,我们可以testingItem通过使用以下命令从 QML 根项搜索 QObject 树来轻松找到QObject::findChild

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

但是,此方法无法找到 QML 中的所有项目,因为某些项目可能没有 QObject 父级。例如,ListView或中的代表Repeater

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
    }
}
Run Code Online (Sandbox Code Playgroud)

对于 中的委托ListView,我们必须搜索视觉子项而不是对象子项。ListViewdelegates 的父级是 ListView 的contentItem. 因此,在 C++ 中,我们必须搜索第ListView一个 (with ),然后在usingQObject::findChild中搜索委托:contentItemQQuickItem::childItems

//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");
    }
}
Run Code Online (Sandbox Code Playgroud)