我正在尝试构建一个内部托管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拥有,因为整个模型都是由它拥有的.所以如果你想在列表被破坏后使用该对象,你必须重新显示或复制它.