QML中如何实现3层嵌套ListModel用于日历月/日/小时展示
3层嵌套ListModel实现方案
可行性确认
完全可以实现小时、日、月3层嵌套的ListModel结构,适配3层嵌套ListView的日历展示需求。
报错原因说明
你遇到的hourlistModel未定义错误,和嵌套结构本身无关,是嵌套ListView绑定模型时的路径错误导致:
QML的ListElement中定义的数组类型属性会自动封装为独立的子ListModel,子模型隶属于上级的每个ListElement实例,没有全局id,不能直接通过id访问,必须通过当前delegate的model对象逐层获取。
绑定规则
3层ListView的模型绑定必须遵循层级路径:
- 最外层(月级)ListView绑定全局的
monthlistModel - 中间层(日级)ListView绑定月级delegate中当前项的
model.daylistModel - 最内层(小时级)ListView绑定日级delegate中当前项的
model.hourlistModel
完整实现代码
推荐方案:动态生成全量模型
不需要手动编写上千个ListElement,在模型初始化时自动生成12个月、每月31天、每天24小时的完整嵌套结构:
import QtQuick 2.15 import QtQuick.Controls 2.15 // 最外层月列表 ListView { id: monthListView width: 400 height: 600 model: monthlistModel delegate: Item { width: parent.width height: 30 + dayListView.height // 月份标题 Text { text: qsTr("%1月").arg(model.monthName + 1) font.bold: true height: 30 } // 中间层日列表 ListView { id: dayListView anchors.top: parent.top anchors.left: parent.left anchors.leftMargin: 20 width: parent.width - 20 height: count * 30 model: model.daylistModel // 绑定当前月的日模型 delegate: Item { width: parent.width height: 30 + hourListView.height // 日期标题 Text { text: qsTr("%1日").arg(model.day + 1) height: 30 } // 最内层小时列表 ListView { id: hourListView anchors.top: parent.top anchors.left: parent.left anchors.leftMargin: 20 width: parent.width - 20 height: count * 25 model: model.hourlistModel // 绑定当前日的小时模型 delegate: Text { text: qsTr("%1点:%2").arg(model.hour).arg(model.notes) height: 25 } } } } } // 嵌套模型定义 ListModel { id: monthlistModel Component.onCompleted: { // 生成12个月 for(let monthIdx = 0; monthIdx < 12; monthIdx++) { let dayArr = [] // 每个月生成31天,可根据实际月份天数逻辑调整 for(let dayIdx = 0; dayIdx < 31; dayIdx++) { let hourArr = [] // 每天生成24小时 for(let hourIdx = 0; hourIdx < 24; hourIdx++) { hourArr.push({hour: hourIdx, notes: ""}) } dayArr.push({day: dayIdx, hourlistModel: hourArr}) } append({monthName: monthIdx, daylistModel: dayArr}) } } } }
静态写法(仅演示结构)
如果需要手动编写静态元素,正确结构如下:
ListModel{ id:monthlistModel ListElement { monthName: 0 daylistModel:[ ListElement { day: 0 hourlistModel: [ ListElement{ hour:0; notes:"" } // 剩余23个小时的ListElement在此补充 ] } // 剩余30个天的ListElement在此补充 ] } // 剩余11个月份的ListElement在此补充 }
内容的提问来源于stack exchange,提问作者cgiannakidis
相关产品推荐
相关产品推荐

