Qt Model/View 架构
一、核心架构基础
1.1 Model(模型)介绍
- Qt Model 是 Qt 的一个重要组件,用于管理和展示数据。它是 Qt 的 Model/View 架构的核心部分,用于将数据模型与其视图相分离,实现数据的高效处理和可视化呈现
- Qt Model 可以理解成一组数据结构,其中包含了待展示的数据,以及有关这些数据的元数据信息,如列名、列类型、数据行数等。Qt Model 还提供了一系列接口,用于访问和操作这些数据,使得开发人员可以轻松地实现数据的增删改查等操作
- Qt Model 支持多种数据模型,包括基于内存、文件、数据库等不同类型的数据源,开发人员可以根据实际需求选择合适的数据模型。此外,Qt Model 也提供了多种视图组件,如 QListView、QTableView、QTreeView 等,用于将数据以不同的方式展示出来,同时也支持自定义视图组件。
QStandardItemModel 现成表格模型,不用重写任何函数 QAbstractTableModel 自定义表格模型,要重写函数 QAbstractListModel 列表模型,要重写函数 QFileSystemModel 文件浏览器,读取本地磁盘/文件夹 1.2 View(视图)介绍
- Qt View 是一个跨平台的应用程序,用于在多个设备上查看 RTSP 和 HTTP 播放器。它使用Qt框架的嵌入式Web服务器和界面库,为用户提供了一个简单、易用的图形用户界面,支持实时视频流的播放、录像回放、抓拍等功能。Qt View 可以运行在多个操作系统,包括 Windows,Linux,Android 和 iOS 等。它广泛应用于监控系统、视频会议、视频门禁、家庭安防等领域。Qt View 被广泛应用于开源软件中,例如 ZoneMinder、iSpy、Bluecherry 和 Zoneminder-Moonlight。
QTableView 表格展示 QListView 列表展示 QTreeView 树形展示
- 视图与模型的绑定:view->setModel(&model) (核心函数:绑定后view自动从model上获取数据)
1.3 Delegate(代理)介绍
- Qt Delegate是一种Qt框架中的重要组件,用于在数据模型和视图之间提供交互性。它可以用于自定义Qt控件的外观和行为,以满足特定的应用程序需求。
Qt Delegate通常用于实现以下功能:
为视图中的项目创建自定义外观,并定制数据的显示方式。
在编辑模式下,为单元格提供自定义编辑器以编辑数据。
实现特定的用户交互行为,如拖放、复制和粘贴等。
1.4 三者关系
总之,先通过建立模型,在通过视图绑定模型才能展示数据。
二、模型详细介绍
2.1 QFileSystemModel
QFileSystemModel是 Qt Model/View 架构中封装操作系统文件系统的专属模型,无需你手动读取文件、解析目录,就能自动同步本地文件 / 文件夹的所有信息(名称、路径、大小、类型、修改时间等),并完美适配QTreeView(树形目录)、QListView(文件列表)、QTableView(文件详情表格),是实现 “文件浏览器” 类功能的核心组件。#include "mainwindow.h" #include "modelextend.h" #include<QObject> #include <QApplication> #include <QAbstractItemView> #include <QAbstractItemModel> #include <QSplitter> #include <QFileSystemModel> #include <QTreeView> #include <QTableView> #include <QListView> #include <QModelIndex> int main(int argc, char *argv[]) { QApplication a(argc, argv); QFileSystemModel model;//获取磁盘文件目录的模型 model.setRootPath("");//设置数据根目录 QTreeView tree;//树形视图 QListView list;//列表视图 QTableView table;//表视图 //设置视图模型(视图绑定模型) tree.setModel(&model); list.setModel(&model); table.setModel(&model); //详细说 tree.setSelectionMode(QAbstractItemView::SingleSelection); list.setSelectionModel(tree.selectionModel()); table.setSelectionModel(tree.selectionModel()); //信号与槽 //双击事件(lambda表达式) QObject::connect(&tree, &QTreeView::doubleClicked, [&](const QModelIndex index){ list.setRootIndex(index); }); QObject::connect(&tree, &QTableView::doubleClicked, [&](const QModelIndex index){ table.setRootIndex(index); }); //初始化一个分割窗口 QSplitter *qsp = new QSplitter(); qsp->addWidget(&tree); qsp->addWidget(&list); qsp->addWidget(&table); qsp->setWindowTitle("模型(Model)测试"); qsp->show(); return a.exec(); }
setSelectionMode 定义单个视图的选中规则(能选多少、以什么方式选) 仅当前视图
NoSelection 不可选中,纯展示 SingleSelection 仅单选,选新取消旧 MultiSelection 点击即多选(无需 Ctrl) ExtendedSelection Ctrl + 点击多选、Shift + 点击选连续项 setSelectionModel 让多个视图共享同一个选择模型( QItemSelectionModel)多视图联动
2.2 QAbstractTableModel
QAbstractTableModel是 Qt Model/View 架构中专门用于定制表格数据展示的抽象类(继承自QAbstractItemModel),它本身无法直接实例化,必须通过继承并重写核心函数,才能将你自定义的数据源(如结构体、数组、数据库结果)绑定到QTableView等视图控件。相比开箱即用的QStandardItemModel,它更轻量、定制化更强,是实现复杂表格逻辑(如动态数据、条件样式、自定义编辑)的核心。2.2.1 必重写函数
rowCount() 返回行数 int rowCount(const QModelIndex &parent) const override; columnCount() 返回列数 int columnCount(const QModelIndex &parent) const override; data() 返回单元格数据 QVariant data(const QModelIndex &index, int role) const override; 2.2.2 可扩展的重写函数
headerData() 设置表头文本 QVariant headerData(int section, Qt::Orientation orientation, int role) const override; setData() 单元格编辑 virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override; flags() 设置单元格属性 virtual Qt::ItemFlags flags(const QModelIndex &index) const override; insertRow()s/removeRows()/insertColumns()/removeColumns() 增删行列 virtual bool insertRows(int row, int count, const QModelIndex &parent) override;
virtual bool insertColumns(int column, int count, const QModelIndex &parent) override;
virtual bool removeRows(int row, int count, const QModelIndex &parent) override;
virtual bool removeColumns(int column, int count, const QModelIndex &parent) override;//------------------------------modelextend.h------------------------------- #ifndef MODELEXTEND_H #define MODELEXTEND_H #include <QAbstractTableModel> #include <QVector> #include <QMap> class ModelExtend : public QAbstractTableModel { Q_OBJECT public: explicit ModelExtend(QObject *parent = nullptr); public: QVector<int> emphindex; QVector<int> empnameidex; QMap<int, QString> empno; QMap<int, QString> empname; QMap<int, QString> empdepartment; //创建字符串列表 QStringList viewtabletitle;//标题名称 void modelFunc(); // QAbstractItemModel interface public: int rowCount(const QModelIndex &parent) const override;//返回行 int columnCount(const QModelIndex &parent) const override;//返回列 QVariant data(const QModelIndex &index, int role) const override;//显示数据 QVariant headerData(int section, Qt::Orientation orientation, int role) const override;//表头数据/标题 }; #endif // MODELEXTEND_H ///-------------------------modelextend.cpp-------------------------------------------------------- #include "modelextend.h" ModelExtend::ModelExtend(QObject *parent) : QAbstractTableModel{parent} { empno[1] = "2022001"; empno[2] = "2022002"; empno[3] = "2022003"; empno[4] = "2022004"; empno[5] = "2022005"; empname[1] = "张三"; empname[2] = "李四"; empname[3] = "王五"; empname[4] = "周发"; empname[5] = "王平"; empdepartment[1] = "营销部"; empdepartment[2] = "财务部"; empdepartment[3] = "研发部"; empdepartment[4] = "董事会"; empdepartment[5] = "后勤部"; //视图标题 viewtabletitle<<"员工编号" << "员工姓名" << "所在部门"; emphindex<< 1 << 2 << 3 << 4 << 5; empnameidex << 1 << 2 << 3 << 4 << 5; modelFunc(); } void ModelExtend::modelFunc() { } int ModelExtend::rowCount(const QModelIndex &parent) const { return 5; } int ModelExtend::columnCount(const QModelIndex &parent) const { return 3; } //index存储(行,列)data函数用于显示数据 QVariant ModelExtend::data(const QModelIndex &index, int role) const { if(!index.isValid()){//判断是否合法 return QVariant();//不合法返回空的值 } if(role == Qt::DisplayRole){//显示文本 switch (index.column()) { case 0: return empno[emphindex[index.row()]]; break; case 1: return empname[empnameidex[index.row()]]; break; case 2: return empdepartment[index.row() + 1]; break; default: return QVariant(); break; } } return QVariant(); } //设置行列表头 QVariant ModelExtend::headerData(int section, Qt::Orientation orientation, int role) const { //if(section > 3 || section < 0) return QVariant(); //显示表头(水平标题) if(role == Qt::DisplayRole && orientation == Qt::Horizontal){ return viewtabletitle[section]; }else if(role == Qt::DisplayRole && orientation == Qt::Vertical){//垂直方向的表头 return section + 1; } return QVariant(); } //--------------------------------------main.cpp---------------------------------------------- #include "mainwindow.h" #include "modelextend.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); // MainWindow w; // w.show(); ModelExtend *model = new ModelExtend(); QTableView view; view.setGeometry(220, 220, 400, 200); view.setModel(model);//创建视图后绑定模型,自动获取模型中的数据 view.show(); return a.exec(); }运行效果:
![]()


浙公网安备 33010602011771号