Skip to content
正常

CustomTableModel 手搓手册

source:成品答案在 model/01-mv-pattern/custom-model/(做完对照)· related:Model/View 章第 1 环

这是「手搓手册」

不是参考手册(查完走),是 workbook(跟着搓)。每个 step 给目标 → 提示 → 检查点,成品 repo 当答案钥匙——卡住了去对照,别整段复制。

0. 你将学到

搓完这个 CustomTableModel,你会打通这几样 Qt 能力(每样后面都有教程深挖,这里先用起来):

  • 自定义模型骨架:继承 QAbstractTableModel + 重写 rowCount/columnCount/data 三件套
  • 多角色 data:一个单元格同时回答 DisplayRole/EditRole/TextAlignmentRole/BackgroundRole/ToolTipRole 等多种问题
  • 可编辑模型flagsItemIsEditable + setData 回写数据 + 发 dataChanged
  • 增删行协议insertRows/removeRowsbeginInsertRows/endInsertRows 包夹容器改动
  • 表头headerData 给列标题和行号
  • 模型与视图解耦:QTableView 只通过模型接口拿数,换数据源不动视图

1. 起点

先有个能跑的空壳。新建最小 Qt Widgets 工程,main 里弹个窗:

C++
#include <QApplication>
#include <QTableView>
#include <QWidget>
#include <QVBoxLayout>
int main(int argc, char* argv[]) {
    QApplication app(argc, argv);
    QWidget w;
    auto* layout = new QVBoxLayout(&w);
    layout->addWidget(new QTableView); // 先放个空表视图
    w.resize(500, 300);
    w.show();
    return app.exec();
}

弹出空白表 = 环境通了,往下走。Model/View 概念不熟先看 Model/View 入门QTableView 基础

2. 任务清单

分 3 阶段 6 步,每步:目标 → 提示 → 检查点。卡住翻 卡住怎么办

阶段Step目标
阶段一:骨架1定义 Task 结构体 + 列枚举01
2rowCount/columnCount/data(DisplayRole) 让表有内容01
阶段二:能力3多角色 data(对齐/底色/悬停) + headerData02
4可编辑:flags + setData + dataChanged02
阶段三:动态5insertRows/removeRows 配 begin/end 信号03
6便捷 API appendTask + demo 增删行按钮03

成品对照:model/01-mv-pattern/custom-model/(按 成品导览 的「怎么读」顺序对照)。

3. 进阶挑战(可选)

搓完基础版想再深一层:

  • 排序:重写 sort(int column, Qt::SortOrder),按列对 tasks_ 重排,发 layoutAboutToBeChanged/layoutChanged。思考:排序要不要保留原行号映射?
  • 过滤:再子类化 QSortFilterProxyModel,按「只看未完成」过滤。提示:代理模型不改源数据,是插在视图和源模型之间的一层。
  • 布尔列用复选框:step 4 的 done 列改成 Qt::CheckStateRole 显示勾选框,setData 同时响应 EditRole 和 CheckStateRole。这是另一种编辑交互范式。
  • 下一站:代理模型(proxy model)/ 自定义委托(QStyledItemDelegate)——换数据层换编辑器,模型骨架不变。

AwesomeQt v0.3.0-13-g31f4d47 · 31f4d47 · 2026-09-22 · CHECKED-BY: CI