You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QML嵌套ListView无/有ListModel时如何存储数据并实现持久化恢复

结论先行

  1. 你最初认为「整数model场景下无法借助model存储数据」的认知不正确,但你切换为ListModel的方案是更合理的选择,当前用ListModel的场景完全可以实现notesLabel数据的持久化存储。
  2. 之前滚动丢失内容的核心原因是你把备注数据存在了视图层(委托的Label控件属性),而ListView委托销毁时会清空视图层所有状态,只要把数据统一存在Model层就能解决滚动丢失问题,再通过本地存储模块就能实现跨重启持久化。

具体实现步骤

第一步:调整ListModel结构,新增note存储字段

你当前的三层ListModel只有基础的时间维度字段,需要在小时维度的model元素中新增note字段用于存储备注内容,建议同时将三层ListModel改为嵌套结构,更符合日历的层级逻辑,避免独立model索引匹配出错:

ListModel{
    id:monthlistModel
    Component.onCompleted:{
        for (var k=0; k <=11; k++){
            // 每个月份元素下挂载对应日期的ListModel
            let dayModel = createDayModel()
            append({
                monthName : k,
                dayModel: dayModel
            })
        }
    }
    function createDayModel(){
        let dayModel = ListModel.create()
        for (var j=0; j <= 31; j++){
            // 每个日期元素下挂载对应小时的ListModel
            let hourModel = createHourModel()
            dayModel.append({
                day : j,
                hourModel: hourModel
            })
        }
        return dayModel
    }
    function createHourModel(){
        let hourModel = ListModel.create()
        for (var i = 0; i <24; i++){
            hourModel.append({
                hour : i,
                note: "" // 新增note字段,初始为空
            })
        }
        return hourModel
    }
}

三层ListView的model对应绑定嵌套的model即可:

  • 月份ListView的model绑定monthlistModel
  • 日期ListView的model绑定model.dayModel
  • 小时ListView的model绑定model.hourModel

第二步:绑定视图控件到model数据,不要直接操作视图属性

将小时委托中的notesLabel的text属性直接绑定到model的note字段,所有数据修改都操作model层,不要直接修改控件属性:

Label{
    id:notesLabel                                        
    anchors.left:hourweeklistviewLabel.right
    anchors.leftMargin: 30
    text: model.note // 直接绑定model数据,委托重建时会自动从model拉取数据
}

在根组件新增几个临时属性用于弹窗传值,避免通过不稳定的currentItem拿视图数据:

property int currentMonthIdx: 0
property int currentDayIdx: 0
property int currentHourIdx: 0
property string currentEditingNote: ""

小时条目的MouseArea点击逻辑改为:

onClicked:{
    currentMonthIdx = monthofdayCalendar.currentIndex
    currentDayIdx = dayCalendar.currentIndex
    currentHourIdx = index
    currentEditingNote = model.note
    windowLoader.active = true
}

第三步:修改弹窗保存逻辑,直接修改model数据

弹窗中的TextField初始值直接绑定currentEditingNote,保存按钮的点击逻辑改为直接修改对应model的note字段,修改后视图会自动同步更新:

Button {
    id: button
    text: qsTr("Add Note")
    anchors.centerIn:parent
    onClicked: {
        // 直接修改model层数据,视图自动同步
        monthlistModel.get(currentMonthIdx).dayModel.get(currentDayIdx).hourModel.get(currentHourIdx).note = title.text
        windowLoader.active = false
    }
}

这一步完成后,滚动ListView导致委托销毁重建时,notesLabel会自动从model拉取数据,不会再出现内容丢失的问题。

第四步:实现跨重启持久化存储

借助Qt.labs.settings模块将model数据序列化存储到本地,应用启动时读取回填即可:

  1. 首先引入Settings模块:
import Qt.labs.settings 1.0
  1. 在根组件添加Settings实例:
Settings {
    id: appSettings
    property string calendarNotes: ""
}
  1. 应用关闭时,将三层model中的note数据序列化为JSON字符串存入Settings:
ApplicationWindow{
    id:appwindow
    onClosing: {
        let notesData = []
        for(let m=0;m<monthlistModel.count;m++){
            let monthItem = monthlistModel.get(m)
            notesData[m] = []
            for(let d=0;d<monthItem.dayModel.count;d++){
                let dayItem = monthItem.dayModel.get(d)
                notesData[m][d] = []
                for(let h=0;h<dayItem.hourModel.count;h++){
                    notesData[m][d][h] = dayItem.hourModel.get(h).note
                }
            }
        }
        appSettings.calendarNotes = JSON.stringify(notesData)
    }
}
  1. 应用启动、model初始化完成后,读取存储的JSON数据回填到model:
Component.onCompleted: {
    if(appSettings.calendarNotes !== ""){
        let notesData = JSON.parse(appSettings.calendarNotes)
        for(let m=0;m<notesData.length;m++){
            let monthItem = monthlistModel.get(m)
            for(let d=0;d<notesData[m].length;d++){
                let dayItem = monthItem.dayModel.get(d)
                for(let h=0;h<notesData[m][d].length;h++){
                    dayItem.hourModel.get(h).note = notesData[m][d][h]
                }
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者cgiannakidis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 16:24:05