当前位置: 首页 > news >正文

Qt/QML DelegateModel基础用法示例

要理解 Qt Quick 中的 DelegateModel,需要从模型-视图架构的核心矛盾入手:如何高效管理数据与视图呈现的解耦,尤其是当同一数据需要在多个视图(列表/网格/卡片)中以不同形式展示时。

一、DelegateModel 是什么?

DelegateModel 是 Qt Quick 提供的模型-委托管理组件,本质是 QAbstractItemModel 的 QML 实现。它的核心目标是:

  • •将模型数据与**视图委托(Delegate)**的渲染逻辑分离;
  • •允许同一数据模型被多个视图共享,每个视图使用不同的委托样式
  • •内部管理委托的创建、回收与生命周期,优化滚动性能。

二、核心定位:解决什么问题?

传统 Qt Quick 开发中,若需让同一数据在多个视图中呈现不同样式,常见做法是为每个视图单独定义 ListModel + delegate,导致:

  • •数据重复维护(多份 ListModel);
  • •数据同步困难(修改一处需同步多处);
  • •性能浪费(重复创建委托实例)。

DelegateModel 解决了这些问题:

  • 数据只存一份:多个 DelegateModel 实例可共享同一数据模型;
  • 委托独立配置:每个 DelegateModel 可定义自己的 delegate,适配不同视图;
  • 自动同步更新:数据变化时,所有依赖该模型的视图都会收到通知。

三、核心结构与关键属性

DelegateModel 继承自 QAbstractItemModel,因此具备标准模型的接口(rowCount/data/roleNames)。其核心组成如下:

1. 模型数据(Model Data)

DelegateModel 的数据来源可以是:

  • •内部的 ListModel(直接定义在 model 属性中);
  • •外部模型(通过 model 属性绑定,比如 FileSystemModel 或自定义 C++ 模型)。

示例:定义包含媒体数据的 DelegateModel

DelegateModel {id: mediaModel // 核心 DelegateModel 实例// 1. 数据模型:内部 ListModel(可替换为外部模型)model: ListModel {ListElement { filePath: "file:///media/video1.mp4"; thumbnail: "qrc:/thumbs/video1.jpg";duration: "02:30";title: "Video 1"}ListElement { filePath: "file:///media/video2.mp4"; thumbnail: "qrc:/thumbs/video2.jpg";duration: "01:45";title: "Video 2"}}
}

2. 委托(Delegate)

delegate 属性定义了每个数据项的渲染逻辑,是一个 QML 组件。它通过 modelData 访问当前项的数据(或通过 model.roleName 访问自定义角色)。

示例:列表视图的委托(紧凑样式)

delegate: Rectangle {width: ListView.view.width - 20;height: 80;color: "#f0f0f0";radius: 4;// 通过 modelData 访问数据(或 model.filePath/model.title)Image { source: modelData.thumbnail; width: 60; height: 60; anchors.left: parent.left; anchors.verticalCenter: parent.verticalCenter; anchors.margins: 10}Column {anchors.left: parent.left; anchors.right: parent.right; anchors.verticalCenter: parent.verticalCenter; anchors.margins: 10; spacing: 5Text { text: modelData.title; font.bold: true; font.pixelSize: 16 }Text { text: modelData.duration; font.pixelSize: 12; color: "#666" }}
}

四、关键特性:为什么选择 DelegateModel?

1. 多视图共享同一数据

同一 DelegateModel 实例可被多个视图(ListView/GridView/Repeater)使用,每个视图仅需指定自己的 delegate

示例:同一模型在 ListView 和 GridView 中的不同呈现

// 共享数据模型的两个 DelegateModel(可选,也可直接用一个实例)
DelegateModel {id: listDelegateModelmodel: mediaModel.model // 共享 mediaModel 的数据delegate: ... // 列表紧凑样式
}DelegateModel {id: gridDelegateModelmodel: mediaModel.model // 共享数据delegate: Rectangle {width: 150; height: 150;color: "#eee";Image { source: model.thumbRole; width: 120; height: 120 }Text { text: model.titleRole; anchors.centerIn: parent }}
}// 主界面:ListView 使用 listDelegateModel
ListView { model: listDelegateModel; anchors.fill: parent }// 详情页:GridView 使用 gridDelegateModel
GridView { model: gridDelegateModel; cellWidth: 160; cellHeight: 160; anchors.fill: parent }

2. 动态切换委托

无需重建视图,只需修改 DelegateModel 的 delegate 属性,即可动态改变项的呈现样式。

示例:点击按钮切换列表/详细模式

Button {text: "切换详细模式"onClicked: {// 切换 DelegateModel 的委托mediaModel.delegate = detailedDelegate;}
}Component {id: detailedDelegateRectangle {width: ListView.view.width - 20;height: 120;// 更详细的布局...}
}

3. 委托生命周期管理

DelegateModel 内部维护委托回收池

  • •当项滚出视图时,委托不会被销毁,而是回收到池中;
  • •下次需要渲染同类项时,直接从池中复用,避免频繁创建/销毁 QML 对象,提升滚动性能。

4. 数据与呈现完全解耦

数据模型(model)和委托(delegate)是独立的组件:

  • •修改数据模型(如新增字段)无需调整委托(只需更新角色或 modelData 访问逻辑);
  • •修改委托样式(如颜色/布局)无需改动数据模型。

五、进阶用法

1. 嵌套 DelegateModel(层级数据)

可将一个 DelegateModel 作为另一个的 model,实现树形结构(如文件夹/文件列表):

DelegateModel {id: rootModelmodel: ListModel {ListElement { name: "Videos"; type: "folder" }}delegate: Item {// 文件夹项:嵌套子 DelegateModelColumn {Text { text: model.name }ListView {model: rootModel.get(model.index).children // 子模型delegate: ... // 文件项委托}}}
}

2. 结合异步加载(图片/数据)

委托中可使用 AsyncImageLoader 实现懒加载,避免阻塞主线程:

delegate: Rectangle {AsyncImage {source: model.thumbRole;width: 60; height: 60;// 加载失败时显示占位符onStatusChanged: if (status == Image.Error) source = "qrc:/placeholder.png"}
}

3. 自定义委托交互

委托中的交互逻辑(如点击/长按)可通过信号传递给 DelegateModel 或父组件:

delegate: Rectangle {onClicked: {mediaModel.selectItem(model.index); // 通知 DelegateModel 选中项}
}// DelegateModel 中处理选中逻辑
DelegateModel {function selectItem(index) {console.log("选中项:", model.get(index).title);}
}

六、与传统方式的对比

维度传统方式DelegateModel 方式
数据维护多视图需多份 ListModel单份数据模型,多视图共享
委托复用每个视图单独定义 delegate同一模型可配置不同 delegate
数据同步需手动同步多模型数据变化自动通知所有视图
性能重复创建委托,滚动卡顿委托回收池,性能更优

七、总结

DelegateModel 是 Qt Quick 中数据与呈现解耦的核心组件,通过封装模型数据和委托管理,解决了多视图共享数据的痛点。它的价值在于:

  • 降低维护成本:数据只存一份,委托独立配置;
  • 提升性能:委托回收池优化滚动体验;
  • 增强灵活性:动态切换委托,适配不同场景。

参考资料

  • •Qt 官方文档:DelegateModel
  • •Qt Quick 模型-视图编程:Model/View Programming

惠州大亚湾

http://www.dtcms.com/a/581809.html

相关文章:

  • 使用hping3进行网络协议测试与防火墙测试的完整指南
  • 西安网站建设市场烟台网站建设团队
  • 如何使用指标来确定趋势
  • 【vsftpd】centos和ubuntu部署vsftpd服务
  • 各大网站发布seo点击
  • Apache Jena SPARQL 查询完全指南:入门与实战案例
  • 做电影网站成本响应式网站开发asp
  • 中文网站开发语言wordpress广告模板下载地址
  • Elimination英文单词学习
  • S31-WinCC单个窗口多次调用
  • 突破罕见遗传病诊断壁垒:知识图谱增强医学大模型的智能应用
  • linux下移植LVGL v9.1.0实现屏幕UI显示
  • 【ETCD】ETCD——confd配置管理
  • C++进阶:(七)红黑树深度解析与 C++ 实现
  • HBase Shell里表操作实战
  • ESP32 FreeRTOS IPC机制全解析
  • 建设银行信用卡卡网站温州微网站制作公司哪家好
  • 虚幻引擎5 GAS开发俯视角RPG游戏 P07-07 激活能力
  • [特殊字符] 常用 Maven 命令
  • 简单的智能数据分析程序
  • 网页制作元素有哪些前端角度实现网站首页加载慢优化
  • C++中的智能指针std::shared_ptr是线程安全的吗?以及它的详细实现原理
  • 网站服务器安装教程视频教程电子商务网站规划
  • 【vsftpd报错】227 Entering Passive Mode,553 Could not create file.
  • 有多少网站可以推广业务那个公司做app
  • 正规的大连网站建设a963中华室内设计官网
  • 中承信安信创软件检测:CMA资质+国家标准双重保障的测试报告
  • #智能CI/CD流水线与AIOps 论坛@AiDD深圳站
  • 医疗AI模型与控制器自动化CI/CD流水线
  • NumPy -数组运算与操作