如何从 C++ 访问 QML ListView 委托项目?
Posted
技术标签:
【中文标题】如何从 C++ 访问 QML ListView 委托项目?【英文标题】:How to access QML ListView delegate items from C++? 【发布时间】:2016-04-21 10:57:49 【问题描述】:在 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");
【问题讨论】:
你应该至少从一个有效的代码开始。此外,您应该尽量减少从 C++ 到 QML 的访问,在这种情况下肯定不会。如果您想要 C++ 端的模型数据,请使用 C++ 模型。 我在做自动化测试,我无法使用模型数据进行验证,所以在qml中显示列表视图后,我需要将qml中的数据提取到C++并进行验证。 我怀疑它是否会像您期望的那样工作,您将有更好的机会在 QML 中迭代列表视图并将文本传递给插槽函数将文本发送到 C++。 由于我在做自动化测试,我无法编辑/触摸 qml,而是使用 qml 插件,这样应用程序就不会受到自动化测试代码的干扰。 在 QML 中进行 QML 测试:doc.qt.io/qt-5/qtquick-qtquicktest.html 【参考方案1】:您可以使用 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
,我们可以通过使用 QObject::findChild
从 QML 根项搜索 QObject 树轻松找到 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 父级。例如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
对于ListView
中的委托,我们必须搜索visual child 而不是子对象。 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");
【讨论】:
以上是关于如何从 C++ 访问 QML ListView 委托项目?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 QML 中的列表视图访问 currentItem 的角色?