Qt模型-视图架构

引言

在GUI开发中,数据与界面的同步一直是核心挑战。传统方法将数据存储在界面组件内部容器中,容易引发数据冗余和同步问题。Qt的模型-视图(Model-View)架构通过解耦数据与界面,提供了更优雅的解决方案。本文将深入剖析Qt模型视图机制,并结合实例演示常见数据模型与视图组件的使用。

https://img-blog.csdnimg.cn/20201204171112345.png


一、模型视图核心组件

1. 核心概念

  • 数据(Data):原始数据源(数据库、文件、内存结构等)。
  • 模型(Model) :继承自QAbstractItemModel,负责数据访问与管理。
  • 视图(View)QListViewQTableViewQTreeView等组件,负责数据展示。
  • 代理(Delegate):处理数据编辑时的界面交互。

2. 通信机制

通过信号槽机制实现数据变更的实时同步:

  • 模型数据更新 → 触发信号 → 视图自动刷新
  • 用户界面操作 → 通过代理修改 → 模型数据更新

二、常用数据模型

1. 基础模型

模型类 描述
QAbstractListModel 一维列表模型(如字符串列表)
QAbstractTableModel 二维表格模型
QStandardItemModel 通用模型,支持树形/表格结构

2. 文件系统模型

QFileSystemModel:直接关联本地文件系统,自动同步目录结构。

3. 数据库模型

模型类 特性
QSqlQueryModel 只读模型,适合显示查询结果
QSqlTableModel 可编辑模型,直接映射单表数据
QSqlRelationalTableModel 支持外键关联,将代码字段转换为可读文本

三、视图组件实战

示例1:QStandardItemModel创建表格

cpp

Copy

cpp 复制代码
#include <QTableView>
#include <QStandardItemModel>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    
    // 创建视图与模型
    QTableView *tableView = new QTableView;
    QStandardItemModel *model = new QStandardItemModel();
    
    // 设置表头
    model->setHorizontalHeaderLabels({"ID", "User Name", "City", "Score"});
    
    // 填充10行数据
    for(int i=0; i<10; i++){
        model->setItem(i, 0, new QStandardItem(QString("100%1").arg(i)));
        model->setItem(i, 1, new QStandardItem(QString("User%1").arg(i)));
        model->setItem(i, 2, new QStandardItem("Shanghai"));
        model->setItem(i, 3, new QStandardItem("80"));
    }
    
    // 自适应列宽
    tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    tableView->setModel(model);
    tableView->show();
    
    return app.exec();
}

效果说明:生成一个4列的表格,数据动态生成,列宽自适应窗口。


示例2:QSqlQueryModel读取数据库

cpp

Copy

cpp 复制代码
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("testDB");
db.setUserName("root");
db.setPassword("123456");

if (db.open()) {
    QSqlQueryModel *model = new QSqlQueryModel;
    model->setQuery("SELECT * FROM student");
    
    // 设置列标题
    model->setHeaderData(0, Qt::Horizontal, "学号");
    model->setHeaderData(1, Qt::Horizontal, "姓名");
    
    QTableView *view = new QTableView;
    view->setModel(model);
    view->show();
}

注意QSqlQueryModel为只读模型,需通过QSqlTableModel实现编辑功能。


示例3:QSqlRelationalTableModel关联外键

cpp

Copy

cpp 复制代码
QSqlRelationalTableModel *model = new QSqlRelationalTableModel;
model->setTable("employees");
model->setRelation(2, QSqlRelation("departments", "dept_id", "dept_name"));
model->select();

QTableView *view = new QTableView;
view->setModel(model);
view->setItemDelegate(new QSqlRelationalDelegate(view)); // 启用关联代理

优势:部门ID自动显示为部门名称,编辑时以下拉框形式选择。


四、性能优化技巧

  1. 分页加载 :对于大数据集,通过fetchMore()动态加载。
  2. 模型复用:避免频繁创建/销毁模型,尤其是数据库模型。
  3. 委托定制 :继承QStyledItemDelegate实现复杂单元格渲染。

五、总结

Qt模型-视图架构通过清晰的职责分离,显著提升了GUI应用的维护性和扩展性。开发者在实际项目中可根据需求选择合适模型:

  • 简单数据结构QStandardItemModel
  • 数据库只读QSqlQueryModel
  • 可编辑表格QSqlTableModel
  • 外键关联QSqlRelationalTableModel
相关推荐
Scott9999HH5 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社6 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海6 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖7 小时前
JDK 26 新特性详解
java·开发语言
马优晨8 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区10 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大10 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai11 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜11 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa11 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio