我正在尝试构建一个内部托管GridView的可重用的QML组件. GridView中的每个元素都具有一组在整个应用程序中很常见的行为(主要是显示和基于鼠标的东西).但是,GridView元素中显示的内容会根据用例而有所不同. (也就是说,一个GridView的封装组件相同,但应用程序的其他部分可能使用不同的组件.)
所以,我想做的是每个调用都提供一个代理,它被添加到已经是委托的GridView中的每个元素.换句话说,这样的东西:
MyGrid.qml
import QtQuick 1.1 Rectangle { id: myGrid objectName: "myGrid" property Component internalDelegate property variant internalModel GridView { anchors.fill: parent delegate: Row { Loader { sourceComponent: myGrid.internalDelegate } } model: parent.internalModel } }
这个想法是,GridView代理中的Loader加载了用户提供的委托,它将如下所示:
Main.qml
import QtQuick 1.1 Rectangle { anchors.fill: parent width: 300 height: 200 MyGrid { anchors.fill: parent internalDelegate: Text { text: name } internalModel: ListModel { ListElement { name: "a" } ListElement { name: "b" } } } }
但是,这不行. QML报告“名称”是Text元素中的未知变量.如果我用一个字符串(即“你好”)替换名称变量,它的工作原理就如预期的那样.
我的问题是,如何将“名称”变量传递给internalDelegate,或者更好的是使整个模型可用,因此internalDelegate可以访问它们(因为调用者也正在定义模型).
另一个问题是:有更好的方法吗?
解决方法
我这样解决了:
MyGrid.qml
import QtQuick 1.1 Rectangle { id: myGrid objectName: "myGrid" property Component internalDelegate property variant internalModel GridView { id: grid anchors.fill: parent delegate: Row { Loader { sourceComponent: myGrid.internalDelegate property variant modelData: grid.model.get(index) } } model: parent.internalModel } }
main.qml
导入QtQuick 1.1
Rectangle { anchors.fill: parent width: 300 height: 200 MyGrid { anchors.fill: parent internalDelegate: Text { text: modelData.name } internalModel: ListModel { ListElement { name: "a" } ListElement { name: "b" } } } }
不知道是否“更好”,但代码越来越简单.列表模型在QML中有点尴尬,并不一致.请记住,model.get(index)由GridView拥有,因为整个模型都是由它拥有的.所以如果你想在列表被破坏后使用该对象,你必须重新显示或复制它.