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
相关推荐
雨落在了我的手上1 天前
初识java(八):数组的定义与使用
java·开发语言
贵州晓智信息科技1 天前
曼德勃罗集的 Three.js 实现
开发语言·javascript·ecmascript
xiaoshuaishuai81 天前
C# CUDA 到 OpenCL 迁移
开发语言·windows·c#
AI科技星1 天前
基于平行素数对等腰梯形网格拓扑的完备性证明哥德巴赫猜想1+1
c语言·开发语言·网络·量子计算·agi
聆风吟º1 天前
【C标准库】深入理解C语言 isdigit函数详解:判断字符是否为数字
c语言·开发语言·库函数·isdigit
故事和你911 天前
洛谷-【图论2-4】连通性问题1
开发语言·数据结构·c++·算法·动态规划·图论
RSCompany1 天前
Frida 17 以后 Python API 跑旧版 JS 报 Java is not defined ?一行 import 直接恢复 Frida 16 体验
开发语言·python·逆向·hook·frida·android逆向·frida17
快乐的哈士奇1 天前
对话框打字机效果:Vur + Java/Python 实现
java·开发语言·python
ch.ju1 天前
Java程序设计(第3版)第四章——类的组成
java·开发语言
我命由我123451 天前
PHP - PHP 基本随机数生成函数
开发语言·ide·后端·java-ee·php·intellij-idea·intellij idea