QML中DelegateModel内Repeater的模型访问失败问题
问题描述
尝试访问DelegateModel内部Repeater的模型时遇到异常:当Repeater中仅使用Text元素时,模型可正常访问,Text能正确获取modelData;但使用具备拖拽功能的自定义FruitTile元素时,Repeater模型无法访问,Tile内的Text无法读取模型数据。
用户代码示例:
FruitTile.qml
import QtQuick 2.6 Rectangle { id: root required property Item dragParent signal pressed signal released signal clicked property int visualIndex: 0 anchors { // horizontalCenter: parent.horizontalCenter // verticalCenter: parent.verticalCenter } radius: 3 MouseArea { id: mouseArea anchors.fill: parent drag.target: root onClicked: root.clicked() onPressed: root.pressed() onReleased: { parent.Drag.drop() root.released() } } Drag.active: mouseArea.drag.active Drag.source: root Drag.hotSpot.x: root.width / 2 Drag.hotSpot.y: root.height / 2 states: [ State { when: mouseArea.drag.active ParentChange { target: root parent: root.dragParent } AnchorChanges { target: root anchors.horizontalCenter: undefined anchors.verticalCenter: undefined } } ] }
DelegateTestModel.qml
import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQml.Models 2.2 Rectangle { id:rootTest width: 600; height: 100 GridView { anchors.fill: parent model: visualModel } DelegateModel { id: visualModel model: fruitDrinksModel delegate: DelegateDelegateModel { } } ListModel { id: fruitDrinksModel ListElement { name: "Apple Cider" color: "blue" modelIndex: 0 } } }
DelegateDelegateModel.qml
import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQml.Models 2.2 import QtQuick.Layouts 1.15 ColumnLayout { Text { text: "Fruit Drink Name: " + name} Repeater { model: fruitModel FruitTile { anchors.top: modelyData.bottom dragParent: rootTest width: 100; height: 40 border.width: 1 color: "yellow" Text { text: "Fruit Name: " + modelData} //Text { text: "Name: " + model.named + "does not work"} //Text { text: "Name: " + named + "does not work"} } } ListModel{ id: fruitModel ListElement { named: "Appley" } ListElement { named: "Orangie" } ListElement { named: "Bananananee" } ListElement { named: "Sure" } } }
问题原因
自定义QML组件(FruitTile)存在作用域隔离,组件内部无法直接访问Repeater迭代产生的模型上下文(如modelData、model.named)。而Text作为Repeater的直接子项,能直接继承Repeater的模型作用域,所以可以正常读取数据。
解决方案
通过给自定义组件添加属性,将Repeater的模型数据主动传递到组件内部,再在组件内使用这些属性展示数据,同时修正原代码中的拼写错误:
修改后的FruitTile.qml
import QtQuick 2.6 Rectangle { id: root required property Item dragParent // 添加接收模型数据的属性 property string fruitName: "" signal pressed signal released signal clicked property int visualIndex: 0 radius: 3 MouseArea { id: mouseArea anchors.fill: parent drag.target: root onClicked: root.clicked() onPressed: root.pressed() onReleased: { parent.Drag.drop() root.released() } } Drag.active: mouseArea.drag.active Drag.source: root Drag.hotSpot.x: root.width / 2 Drag.hotSpot.y: root.height / 2 states: [ State { when: mouseArea.drag.active ParentChange { target: root parent: root.dragParent } AnchorChanges { target: root anchors.horizontalCenter: undefined anchors.verticalCenter: undefined } } ] }
修改后的DelegateDelegateModel.qml
import QtQuick 2.7 import QtQuick.Controls 2.0 import QtQml.Models 2.2 import QtQuick.Layouts 1.15 ColumnLayout { Text { text: "Fruit Drink Name: " + name} Repeater { model: fruitModel FruitTile { // 修正原代码中的modelyData拼写错误 anchors.top: parent.bottom dragParent: rootTest width: 100; height: 40 border.width: 1 color: "yellow" // 将模型数据绑定到组件属性 fruitName: model.named // 使用组件内部属性读取数据 Text { text: "Fruit Name: " + parent.fruitName} } } ListModel{ id: fruitModel ListElement { named: "Appley" } ListElement { named: "Orangie" } ListElement { named: "Bananananee" } ListElement { named: "Sure" } } }
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

