什么是QT中的QAbstractTableModel类?

QAbstractTableModelQt 框架中模型/视图架构的核心类之一,处理表格数据的基石类,专门用于为表格形式的数据(二维表格)提供模型支持。它继承自QAbstractItemModelQTableView视图组件的理想搭档。通过重写关键函数实现:

  1. 定义表格结构(行/列数)
  2. 提供单元格数据
  3. 支持编辑和样式定制 它赋予开发者完全控制表格行为的能力,是实现复杂表格视图的首选方案。

核心作用

  1. 数据抽象层
    将原始数据(如数据库、文件、内存结构)抽象为表格结构(行和列),供 QTableView 等视图组件显示和编辑。
  2. 解耦数据与UI
    遵循 MVC(Model-View-Controller) 设计模式,分离数据逻辑与界面渲染。

必须重写的关键虚函数

函数签名作用示例返回值
int rowCount(const QModelIndex &parent) const返回行数myData.size()
int columnCount(const QModelIndex &parent) const返回列数myData[0].size()
QVariant data(const QModelIndex &index, int role) const返回单元格数据return myData[row][col];

常用可选重写函数

  • QVariant headerData(int section, Qt::Orientation orientation, int role) const
    设置表头标题(水平/垂直)。
if (role == Qt::DisplayRole) {
    if (orientation == Qt::Horizontal) 
        return QString("Column %1").arg(section);
    else 
        return QString("Row %1").arg(section);
}
  • bool setData(const QModelIndex &index, const QVariant &value, int role)
    编辑数据时调用(需配合 flags() 启用编辑)。
  • Qt::ItemFlags flags(const QModelIndex &index) const
    设置单元格属性(如可编辑、可选中等):
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;

关键特性

角色(Role)系统
通过 data() 的 role 参数区分数据类型:

  • Qt::DisplayRole:显示的文本(如 "John"
  • Qt::EditRole:编辑时的原始数据
  • Qt::BackgroundRole:单元格背景色
  • Qt::TextAlignmentRole:文本对齐方式
if (role == Qt::BackgroundRole)
    return QBrush(Qt::yellow);
  1. 索引(QModelIndex)
  • 通过 index(row, col) 创建单元格索引
  • 用 index.row() 和 index.column() 获取位置
  1. 数据修改通知
    修改数据后需手动触发信号:
  • 单单元格更新:emit dataChanged(topLeft, bottomRight)
  • 增/删行:调用 beginInsertRows()/endInsertRows()

使用流程

1、继承QAbstractTableModel

class MyModel : public QAbstractTableModel {
    Q_OBJECT
public:
    // 重写虚函数...
}; 

2、实现数据存取

// 示例:内存数据存储
QVector<QVector<QString>> tableData;

3、链接视图

QTableView *view = new QTableView;
MyModel *model = new MyModel;
view->setModel(model); // 绑定模型与视图

使用场景是?

  • 需要显示二维表格数据(如 Excel 样式)
  • 数据需要支持动态修改(增删行/列)
  • 需要自定义单元格样式(颜色、字体等)

样例代码

// 自定义模型
class CustomTableModel : public QAbstractTableModel {
public:
    int rowCount(const QModelIndex&) const override { return 3; }
    int columnCount(const QModelIndex&) const override { return 2; }

    QVariant data(const QModelIndex &index, int role) const override {
        if (role == Qt::DisplayRole) 
            return QString("Cell %1,%2").arg(index.row()).arg(index.column());
        return QVariant();
    }
};

// 在视图中使用
QTableView tableView;
CustomTableModel model;
tableView.setModel(&model);
tableView.show(); // 显示3x2表格

对比其他模型类

Qt 提供了超过 10 种模型类支持表格数据展示

在 Qt 的模型/视图架构中,除了您提到的四种模型类(`QAbstractListModel`、`QStandardItemModel`、`QSqlTableModel`、`QAbstractTableModel`),还有**其他重要模型类**可用于表格数据展示。以下是完整的分类总结:

1. 基础抽象模型(必须继承实现)

类名用途表格适用性
QAbstractItemModel所有模型的基类(树/表/列表)★★★
QAbstractTableModel表格专用基础模型★★★
QAbstractListModel单列列表基础模型(如 QListView)

2. 便捷模型(可直接使用)

类名用途表格适用性
QStandardItemModel通用内存模型(支持树/表)简单表格(无需自定义模型)★★★
QStringListModel字符串列表专用模型

3. 数据库模型(直接操作数据库表

类名用途表格适用性
QSqlTableModel单数据库表模型★★★
QSqlQueryModel只读 SQL 查询结果模型★★★
QSqlRelationalTableModel支持外键关系的表模型★★★

4. 文件系统模型

类名用途表格适用性
QFileSystemModel文件系统浏览器模型★★ (可显示表格)
QDirModel已废弃的文件系统模型

5. 代理模型(数据转换层)

类名用途表格适用性
QSortFilterProxyModel排序/过滤代理★★★
QIdentityProxyModel透明数据传递代理★★★
QTransposeProxyModel行列转置代理★★★
QConcatenateTablesProxyModel多表拼接代理★★★

完整模型类关系图

QAbstractItemModel
├── QAbstractTableModel      // 表格基础
│   ├── QSqlTableModel       // 数据库表
│   ├── QSqlRelationalTableModel
│   └── [Your Custom Model]
├── QAbstractListModel       // 列表基础
│   └── QStringListModel     // 字符串列表
└── QStandardItemModel       // 通用内存模型

代理模型(独立层级):
QAbstractProxyModel
├── QSortFilterProxyModel    // 排序过滤
├── QIdentityProxyModel      // 透明传递
├── QTransposeProxyModel     // 行列转置
└── QConcatenateTablesProxyModel // 表合并

关键模型类详解

1. QSqlQueryModel (重要补充)

  • 用途:显示任意 SQL 查询结果(SELECT语句)
  • 表格适用性:★★★★★

QSqlQueryModel model; model.setQuery("SELECT name, salary FROM employees");
 QTableView view; view.setModel(&model); // 直接显示结果集
  • 优势:比QSqlTableModel更灵活,支持复杂查询
  • 限制:默认只读(需额外代码实现编辑)

2. 代理模型(表格增强神器)

QSortFilterProxyModel:

// 示例:实现实时过滤 QSortFilterProxyModel proxy; proxy.setSourceModel(sourceModel); // 源模型 
proxy.setFilterKeyColumn(0); // 按第一列过滤 proxy.setFilterRegularExpression("John");  view.setModel(&proxy);
  • QTransposeProxyModel
// 行列转置(行变列,列变行)
QTransposeProxyModel proxy; 
proxy.setSourceModel(sourceModel); 
view.setModel(&proxy); // 显示转置后的表格

3. QFileSystemModel (特殊表格)

  • 显示文件系统信息(名称/大小/类型/修改日期)
  • 表格模式
QFileSystemModel model;
 model.setRootPath("/"); 
QTableView view; 
view.setModel(&model);
 view.setRootIndex(model.index("/path")); 

何时选择哪种模型?

场景推荐模型
自定义内存表格QAbstractTableModel 或 QStandardItemModel
数据库单表编辑QSqlTableModel
复杂SQL查询展示QSqlQueryModel
字符串列表QStringListModel
文件浏览器QFileSystemModel
表格排序/过滤QSortFilterProxyModel + 任意源模型
行列转置QTransposeProxyModel

完整代码示例:代理模型组合

// 创建源模型(数据库)
QSqlTableModel sourceModel;
sourceModel.setTable("employees");
sourceModel.select();

// 创建代理链:排序 -> 转置 -> 过滤
QSortFilterProxyModel sortProxy;
sortProxy.setSourceModel(&sourceModel);
sortProxy.sort(0, Qt::AscendingOrder); // 按第0列排序

QTransposeProxyModel transposeProxy;
transposeProxy.setSourceModel(&sortProxy);

QSortFilterProxyModel filterProxy;
filterProxy.setSourceModel(&transposeProxy);
filterProxy.setFilterRegularExpression("Manager");

// 最终视图
QTableView view;
view.setModel(&filterProxy);  // 显示:转置+排序+过滤后的表格

总结

Qt 提供了超过 10 种模型类支持表格数据展示,核心包括:

  1. 基础模型QAbstractTableModelQStandardItemModel
  2. 数据库模型QSqlTableModelQSqlQueryModelQSqlRelationalTableModel
  3. 代理模型QSortFilterProxyModelQTransposeProxyModel(极大扩展表格能力)
  4. 专用模型QFileSystemModelQStringListModel

通过组合基础模型 + 代理模型,几乎可以实现任何复杂度的表格需求

这是 Qt 模型/视图架构的强大之处。

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部