Qt-Model/View综合示例

相关类简介

Qt和Model/View模式相关的类比较多, 但一般存在继承关系, 按model(模型), view(视图), delegate(委托)划分为如下几种:

类型 类名 简介 父类
model
QAbstractItemModel (抽象类)常用的Model的基类 QObject
QStandardItemModel 通用model可以实现以下任意类型的功能 QAbstractItemModel
QAbstractTableModel (抽象类)缺省为二维
主要为 QTableView提供数据
QAbstractItemModel
QAbstractListModel (抽象类)缺省为一维, 单列数据结构(其实现对应QML中的ListModel)
其实现常用于为QListView提供数据, 或为QML中Repeater等提供数据
子类: QStringListModel
QAbstractItemModel
QStringListModel 用于处理字符串列表的数据模型
常用于为QListView提供数据
QAbstractListModel
QFileSystemModel 类似文件结构(目录树)的model
常用于为QTreeView提供数据
QAbstractItemModel
QDirModel 目录结构, 为QTreeView提供数据 QAbstractItemModel
...
view
QAbstractItemView (抽象类)派生关系: QWidget->QFrame->QAbstractScrollArea QAbstractScrollArea
QListView 单方向(一维)列表控件 QAbstractItemView
QTableView 平面(二维)列表控件
构建方式: 用setModel绑定到数据源构建, 单元格一般为文本
其它特性: 支持绑定QSqlTableModel
QAbstractItemView
QTableWidget 同上, 但单元格得到了扩展, 不能使用setModel绑定
构建方式: 不能调用setModel绑定数据源, 只能使用QTableWidgetItem
进行单元格构建, 单元格中可同时放入文本和控件
QTableView
QTreeView 树形结构控件 QAbstractItemView
...
delegate
QAbstractItemDelegate (抽象类)委托的基类 QObject
QItemDelegate 自定义绘制 QAbstractItemDelegate
QStyledItemDelegate (>Qt 4.4版本)默认委托, 加载当前默认style绘制, 一般使用这个类较多. QAbstractItemDelegate
其他 QItemSelectionModel 用于保存当前model被选中的部分:
QItemSelectionModel* selections = m_tableView->selectionModel();
主要方法:
QModelIndexList selectedIndexes();//获取当前选择了多少item
QModelIndexList selectedRows(0);//获取当前(第0列)选择了多少行

QObject
QHeaderView QTableView的表头, 有两个, 一个横向, 一个纵向, 当我们想实现自定义的
表头时, 需要继承该类实现自定义部分, 如: 常见场景是在横向表头的第一
列加一个全选框.
QAbstractItemView

类举例详细介绍

以QAbstractTableModel, QTableView, QStyledItemDelegate举例

QAbstractTableModel

必须实现的虚函数

  • rowCount 返回表格多少行
  • columnCount 返回表格多少列
  • data 返回单元格数据(参数: 单元格索引, 单元格角色(显示, tips, 编辑等), 返回值: 该单元格对应角色的内容)

其它常用接口

  • setData 更新数据

  • sort 排序

  • flags 返回item的标志项, 常用来设置表格是否可选, 是否可以点击复选框

    //设置表格可点击复选框
    Qt::ItemFlags flags(const QModelIndex &index) const 
    {
        if (!index.isValid())
            return QAbstractItemModel::flags(index);
      
        Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
        if (index.column() == 0)    //设置第一列能复选
            flags |= Qt::ItemIsUserCheckable;
      
        return flags;
    }
    

QTableView

必用接口

  • setModel(QAbstractItemModel *model); //设置数据源

常用接口

  • //resizeRowsToContents();//设置自动行高, model中数据量多时设置该选项会严重影响速度

  • resizeColumnsToContents();//设置自动列宽, 一般在setModel后设置才会生效. 速度较快.

  • setWordWrap(false); //取消自动换行

  • setTextElideMode(Qt::ElideNone); //超出文本不显示省略号

  • setItemDelegate(QAbstractItemDelegate *delegate) //设置委托/代理delegate, 比如使用QStyledItemDelegate实现的自定义delegate, 不设置此项的话, 默认使用QStyledItemDelegate

  • setEditTriggers(QAbstractItemView::AllEditTriggers); //禁用所有情况下的单元格编辑

  • setContextMenuPolicy(Qt::CustomContextMenu); //Item的鼠标右键设置为发送QWidget::customContextMenuRequested()信号

  • horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); //表头的鼠标右键设置为发送QWidget::customContextMenuRequested()信号

  • //setSelectionMode(QAbstractItemView::ContiguousSelection);//拖动或按shift或ctrl可以选中多行  
    setSelectionMode(QAbstractItemView::ExtendedSelection); //拖动或按shift能选中多行, 按ctrl可以切换单条item是否选中
    
  • QItemSelectionModel* selections = selectionModel();//获取当前model选择的部分

    QModelIndexList selected = selections->selectedIndexes();//获取当前选择了多少item

    QModelIndexList selected = selections->selectedRows(0);//返回当前选择了多少行

  • setHorizontalHeader(new MyHorizontalHeaderView(Qt::Horizontal, this)); //表头设置为自定义表头, MyHorizontalHeaderView继承自QHeaderView

  • horizontalHeader()->setSectionResizeMode(0,QHeaderView::Fixed); //设置第一列不能改变列宽

    • QHeaderView::Interactive :0 用户可设置,也可被程序设置成默认大小
    • QHeaderView::Fixed :2 用户不可更改列宽
    • QHeaderView::Stretch :1 根据空间,自动改变列宽,用户与程序不能改变列宽
    • QHeaderView::ResizeToContents:3 根据内容改变列宽,用户与程序不能改变列宽

自定义QTableView的一些功能实现代码

我们常常需要给QTableView加上, 表头点击排序, 表头右键菜单, Item项右键菜单等功能:

QStyledItemDelegate

常用接口和信号

  • createEditor 创建一个QWidget(名为editor)用于编辑数据, 返回QWidget*
  • setEditorData 是将model中当前有的数据加载到上面创建的QWidget(editor)上, 自己实现从model中取数据, 和(setValue)放到editor上
  • updateEditorGeometry 设置editor显示到一定位置, 并设定其大小, 使这个editor看起来像是单元格的一部分一样, 用到option.rect
  • setModelData 将editor上的数据保存到model中
  • closeEditor 信号: 表示用户已完成对数据的编辑,可以销毁editor了
  • commitData() 信号: 必须在完成编辑数据之后, 发送该信号, 将会把新数据写回model
  • paint() 和 sizeHint() 如果需要特殊风格绘制单元项中内容, 需要重载这两个函数.

QItemSelectionModel

QHeaderView

常用接口

  • setSectionsClickable(true); //设置表头响应单击
  • setHighlightSections(true); //设置表头有高亮效果

实现自定义绘制部分表头内容

void paintSection(QPainter * painter, const QRect & rect, int logicalIndex ) const
    {
        if (logicalIndex != 0)
            QHeaderView::paintSection(painter, rect, logicalIndex);    //这里只绘制第一列, 故其余列采用系统绘制.
        else
        {
//            qDebug() << "#HorizontalHeaderView# paintSection() " << rect;
            QStyleOptionViewItem opt;    //定义一个小部件对象
            opt.initFrom(this);
            opt.rect = rect;
            if (m_isCheckAll)
                opt.state |= QStyle::State_On;
            else
                opt.state |= QStyle::State_Off;

            style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, painter);
        }
    }
posted @ 2024-04-29 22:13  技术不支持  阅读(94)  评论(0编辑  收藏  举报