由于项目要求,需要实现一个列表目录显示信息,并且需要实现每一项提供进度条和选项框功能,所以需要继承QAbstractTableModel和QStyledItemDelegate进行自定义。

-自定义数据

itemdata.h

  1. #ifndef ITEMDATA_H
  2. #define ITEMDATA_H
  3. #include <QMetaType>
  4. #include <QString>
  5. #include <QDebug>
  6.  
  7. typedef enum{
  8. level_0 = 0,
  9. level_1,
  10. level_2,
  11. level_3,
  12. level_4,
  13. level_5,
  14. level_6,
  15. level_7,
  16. level_8,
  17. level_9,
  18. level_none,
  19. } Priority;
  20.  
  21. typedef enum{
  22. state_0 = 0,
  23. state_1,
  24. state_2,
  25. state_3,
  26. state_4,
  27. state_5,
  28. state_6,
  29. state_7,
  30. state_8,
  31. state_9,
  32. }State;
  33.  
  34. struct Data{
  35. Priority priority;
  36. State taskState;
  37. QString taskCode;
  38. QString taskName;
  39. QString taskType;
  40. QString tubeType;
  41. int tubeNumber;
  42. int rackNumber;
  43. int beginTime;
  44. int processed; //[0-100]
  45. QString taskOwner;
  46. bool select = false;
  47. };
  48.  
  49. Q_DECLARE_METATYPE(Data)
  50.  
  51. #endif // ITEMDATA_H

-继承QAbstractTableModel自定义数据

mytablemodel.h

  1. #ifndef MYTABLEMODEL_H
    #define MYTABLEMODEL_H
  2. #include<QAbstractTableModel>
  3. #include <QList>
  4. #include "itemdata.h"
  5. class myTableModel:public QAbstractTableModel
  6. {
  7. Q_OBJECT
  8. public:
  9. myTableModel(QAbstractTableModel *parent = 0);
  10. ~myTableModel();
  11. QVariant data(const QModelIndex &index, int role) const;// 重写,用于返回数据
  12. int rowCount(const QModelIndex &parent = QModelIndex()) const; // 重写, 反回行数
  13. int columnCount(const QModelIndex &parent = QModelIndex()) const;// 重写,返回列数
  14. QVariant headerData(int section, Qt::Orientation, int role)const;// 重写, 返回列标题
  15. Qt::ItemFlags flags(const QModelIndex &index) const; // 重写, 每一项的操作标识
  16. bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);// 重写, 设置数据
  17. void addData(Data data);// 添加模型数据
  18. private
  19. QStringList _roleNames;
  20. QList<Data> _dataList;
  21. };
  22. #endif // MYTABLEMODEL_H
  1. #include "mytablemodel.h"
  2.  
  3. myTableModel::myTableModel(QAbstractTableModel *parent):QAbstractTableModel(parent),
  4. _roleNames({"priority","taskState","taskCode","taskName","taskType","tubeType","tubeNumber","rackNumber","beginTime","processed","taskOwner","select"}){
  5.  
  6. }
  7.  
  8. myTableModel::~myTableModel(){
  9.  
  10. }
  11.  
  12. QVariant myTableModel::data(const QModelIndex &index, int role) const{
  13. QVariant v;
  14. switch (role - (Qt::UserRole+1)) {// 自定义角色从Qt::UserRole + 1开始
  15. case 0:
  16. v = QVariant(_dataList[index.row()].priority);
  17. break;
  18. case 1:
  19. v = QVariant(_dataList[index.row()].taskState);
  20. break;
  21. case 2:
  22. v = QVariant(_dataList[index.row()].taskCode);
  23. break;
  24. case 3:
  25. v = QVariant(_dataList[index.row()].taskName);
  26. break;
  27. case 4:
  28. v = QVariant(_dataList[index.row()].taskType);
  29. break;
  30. case 5:
  31. v = QVariant(_dataList[index.row()].tubeType);
  32. break;
  33. case 6:
  34. v = QVariant(_dataList[index.row()].tubeNumber);
  35. break;
  36. case 7:
  37. v = QVariant(_dataList[index.row()].rackNumber);
  38. break;
  39. case 8:
  40. v = QVariant(_dataList[index.row()].beginTime);
  41. break;
  42. case 9:
  43. v = QVariant(_dataList[index.row()].processed);
  44. break;
  45. case 10:
  46. v = QVariant(_dataList[index.row()].taskOwner);
  47. break;
  48. case 11:
  49. v= QVariant(_dataList[index.row()].select);
  50. break;
  51. }
  52. return v;
  53. }
  54.  
  55. int myTableModel::rowCount(const QModelIndex &parent) const
  56. {
  57. Q_UNUSED(parent)
  58. return _dataList.size();// 行数
  59. }
  60.  
  61. int myTableModel::columnCount(const QModelIndex &parent) const
  62. {
  63. Q_UNUSED(parent)
  64. return _roleNames.size();//列数
  65. }
  66.  
  67. //QHash<int, QByteArray> myTableModel::roleNames() const
  68. //{
  69. // QHash<int,QByteArray> roleName;
  70. // for(int i = 0; i < _roleNames.size(); ++i){
  71. // roleName.insert(Qt::UserRole+1+i,_roleNames[i].toLocal8Bit());
  72. // }
  73. // return roleName;
  74. //}
  75.  
  76. QVariant myTableModel::headerData(int section, Qt::Orientation orientation, int role)const{
  77. if(role == Qt::DisplayRole && orientation == Qt::Orientation::Horizontal){ //返回列标题
  78. QString sectionName;
  79. switch (section) {
  80. case 0:
  81. sectionName = tr("优先级");
  82. break;
  83. case 1:
  84. sectionName = tr("状态");
  85. break;
  86. case 2:
  87. sectionName = tr("编码");
  88. break;
  89. case 3:
  90. sectionName = tr("名称");
  91. break;
  92. case 4:
  93. sectionName = tr("类型");
  94. break;
  95. case 5:
  96. sectionName = tr("冻存管型号");
  97. break;
  98. case 6:
  99. sectionName = tr("管数量");
  100. break;
  101. case 7:
  102. sectionName = tr("盒数量");
  103. break;
  104. case 8:
  105. sectionName = tr("开始时间");
  106. break;
  107. case 9:
  108. sectionName = tr("进度");
  109. break;
  110. case 10:
  111. sectionName = tr("发起人");
  112. break;
  113. case 11:
  114. sectionName = tr("选中");
  115. break;
  116.  
  117. }
  118. return sectionName;
  119. }
  120. return QVariant();
  121. }
  122.  
  123. void myTableModel::addData(Data data){
  124. beginInsertRows(QModelIndex(),_dataList.count(),_dataList.count()); //添加数据之前进行通知并告知添加到什么位置
  125. _dataList.push_back(data);
  126. endInsertRows();
  127. }
  128.  
  129. Qt::ItemFlags myTableModel::flags(const QModelIndex &index) const {
  130. if(!index.isValid()){
  131. return Qt::NoItemFlags;
  132. }
  133. Qt::ItemFlags flags;
  134. flags = QAbstractItemModel::flags(index);
  135. if(index.column() == 11){
  136. flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable|Qt::ItemIsUserCheckable;// 选项框设置为可选中
  137. } else {
  138.  
  139. flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
  140. }
  141. return flags;
  142. }
  143. bool myTableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
  144. if(role == Qt::UserRole + 1 + 11){// 设置选项框数据true or false
  145. QVector<int> changeRoles;
  146. changeRoles.push_back(Qt::UserRole + 1 + 11);
  147. for(QList<Data>::iterator it = _dataList.begin(); it != _dataList.end(); ++it){
  148. if((*it).taskCode == index.data(Qt::UserRole +1 + 2).toString()){ // 根据taskCode定位选中的数据行
  149. (*it).select = value.toBool();
  150. }
  151. }
  152. emit dataChanged(index,index,changeRoles);
  153. return true;
  154. } else{
  155. return QAbstractTableModel::setData(index, index,role); // 调用默认父类默认实现
  156. }
  157. }

-继承QStyledItemDelegate重写数据项代理,显示各个项,并接收接收处理用户事件

myitemdelegate.h

  1. #ifndef MYITEMDELEGATE_H
  2. #define MYITEMDELEGATE_H
  3. #include <QStyledItemDelegate>
  4. #include <QPainter>
  5. #include <QStyleOptionViewItem>
  6. #include <QRect>
  7. #include <QPainterPath>
  8. #include <QDate>
  9. #include <QTime>
  10. #include <QApplication>
  11.  
  12. #include "itemdata.h"
  13.  
  14. class myItemDelegate:public QStyledItemDelegate
  15. {
  16. Q_OBJECT
  17. public:
  18. myItemDelegate(QStyledItemDelegate * parent = 0);
  19. ~myItemDelegate();
  20.  
  21. void paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const; // 重写,绘制每一项
  22. QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;//重写, 返回项尺寸
  23. bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);// 重写,处理项事件
  24. QRect checkBoxRect(const QStyleOptionViewItem &viewItemStyleOptions) const;//返回选中框尺寸
  25.  
  26. };
  27.  
  28. #endif // MYITEMDELEGATE_H
  1. #include "myitemdelegate.h"
  2. #include <QMouseEvent>
  3.  
  4. myItemDelegate::myItemDelegate(QStyledItemDelegate *parent):QStyledItemDelegate(parent)
  5. {
  6.  
  7. }
  8.  
  9. myItemDelegate::~myItemDelegate(){
  10.  
  11. }
  12.  
  13. void myItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{
  14. if(index.isValid()){
  15. painter->save();
  16. int column = index.column();
  17. QVariant v = index.data(column + (Qt::UserRole+1)); //获取数据
  18. // painter->drawRect(option.rect);
  19.  
  20. QStyleOptionViewItem viewOption(option);
  21. if(0 == column){
  22. Priority priority = (Priority)v.toInt();
  23. painter->drawText(option.rect, Qt::AlignCenter, QString::number(priority));
  24. }else if(1 == column){
  25. State state = (State)v.toInt();
  26. painter->drawText(option.rect, Qt::AlignCenter, QString::number(state));
  27. }
  28. else if(2 == column){
  29. QString taskCode = v.toString();
  30. painter->drawText(option.rect, Qt::AlignCenter,taskCode);
  31. }
  32. else if(3 == column){
  33. QString taskName = v.toString();
  34. painter->drawText(option.rect, Qt::AlignCenter,taskName);
  35. }
  36. else if(4== column){
  37. QString taskType = v.toString();
  38. painter->drawText(option.rect, Qt::AlignCenter,taskType);
  39. }
  40. else if(5 == column){
  41. QString tubeType = v.toString();
  42. painter->drawText(option.rect, Qt::AlignCenter,tubeType);
  43. }
  44. else if(6 == column){
  45. int tubeNumber = v.toInt();
  46. painter->drawText(option.rect, Qt::AlignCenter, QString::number(tubeNumber));
  47. }
  48. else if(7 == column){
  49. int rackNumber = v.toUInt();
  50. painter->drawText(option.rect, Qt::AlignCenter, QString::number(rackNumber));
  51. }
  52. else if(8== column){
  53. int beginTime = v.toInt();
  54. QRect timeRect = QRect(option.rect.left(),option.rect.top(),option.rect.width(),option.rect.height()/2);
  55. QRect dateRect = QRect(option.rect.left(),option.rect.top()+(option.rect.height()/2),option.rect.width(),option.rect.height()/2);
  56. painter->drawText(timeRect,Qt::AlignCenter,QDateTime::fromSecsSinceEpoch(beginTime).toString("hh:mm:ss"));
  57. painter->drawText(dateRect,Qt::AlignCenter,QDateTime::fromSecsSinceEpoch(beginTime).toString("yyyy-MM-dd"));
  58. }
  59. else if(9 == column){// 绘制进度条
  60. int processed = v.toInt();
  61.  
  62. QStyleOptionProgressBar *processBar = new QStyleOptionProgressBar();
  63. processBar->rect = QRect(option.rect.left(),option.rect.top()+(option.rect.height()/3),option.rect.width(),option.rect.height()/3);
  64. processBar->minimum = 0;
  65. processBar->maximum = 100;
  66. processBar->progress = processed;
  67. processBar->text = QString::number(processed)+"%";
  68. processBar->textAlignment = Qt::AlignBottom;
  69. processBar->textVisible = true;
  70. QApplication::style()->drawControl(QStyle::CE_ProgressBar, processBar, painter);
  71. // painter->drawText(option.rect, Qt::AlignCenter, QString::number(processed));
  72. }
  73. else if(10 == column){
  74. QString taskOwner = v.toString();
  75. painter->drawText(option.rect, Qt::AlignCenter,taskOwner);
  76. }
  77. else if(11 == column){ // 绘制选项框
  78. bool checked = v.toBool();
  79. QStyleOptionButton checkButton;
  80. checkButton.state |= QStyle::State_Enabled;
  81. checkButton.state |= checked ? QStyle::State_On : QStyle::State_Off;// 根据模型值设定是否选中
  82. checkButton.rect = checkBoxRect(option);
  83. QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkButton, painter);
  84. }
  85. painter->restore();
  86.  
  87. }
  88. }
  89.  
  90. QSize myItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const{
  91. qDebug()<< option.rect.width()<< option.rect.height();
  92. //return QSize(option.rect.size());
  93. //return QSize(40,60);
  94. return QSize(option.rect.width(), 200);
  95. }
  96. QRect myItemDelegate::checkBoxRect(const QStyleOptionViewItem &viewItemStyleOptions) const {
  97. QStyleOptionButton checkBoxStyleOption;
  98. QRect checkBoxRect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkBoxStyleOption);
  99. QPoint checkBoxPoint(viewItemStyleOptions.rect.x() + (viewItemStyleOptions.rect.width()- checkBoxRect.width())/2,
  100. viewItemStyleOptions.rect.y() + (viewItemStyleOptions.rect.height()- checkBoxRect.height())/2);
  101. return QRect(checkBoxPoint, checkBoxRect.size());
  102. }
  103. bool myItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) {
  104. if(index.column() == 11){
  105. if(event->type() == QEvent::MouseButtonRelease){
  106. QMouseEvent *mouseEvent = (QMouseEvent*)event;
  107. if(mouseEvent->button() == Qt::LeftButton && checkBoxRect(option).contains(mouseEvent->pos())){
  108. bool checked = index.data(Qt::UserRole + 1 + 11).toBool();
  109. return model->setData(index, !checked, Qt::UserRole + 1 + 11);// 单击选中框设置相反的选中状态
  110. }
  111. }
  112. }
  113. return QStyledItemDelegate::editorEvent(event, model, option, index); //其余事件调用默认实现
  114. }

-测试

  1. .../
    QSortFilterProxyModel *sortModel = new QSortFilterProxyModel();
  2. myTableModel *model = new myTableModel();
  3. myItemDelegate *itemDelegate = new myItemDelegate();
  4. ui->tableView->setItemDelegate(itemDelegate);
  5. sortModel->setSourceModel(model);
  6. sortModel->setDynamicSortFilter(true);
  7. sortModel->setSortRole(Qt::UserRole+1); //按照权限排序
  8. ui->tableView->setSortingEnabled(true);
  9. ui->tableView->setModel(sortModel);
  10.  
  11. ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
  12. ui->tableView->setSelectionMode ( QAbstractItemView::SingleSelection);
  13. // ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
  14. ui->tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  15. ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
  16. ui->tableView->resizeColumnsToContents();
  17. ui->tableView->setShowGrid(false);
  18. for(int i = 0 ;i < 10 ; ++i){
  19. Data d;
  20. d.priority = static_cast<Priority>(i);
  21. d.taskState = static_cast<State>(9-i);
  22. d.taskCode = QString("taskCode%1").arg(i);
  23. d.taskName = QString("taskName%1").arg(i);
  24. d.taskType = QString("taskType%1").arg(i);
  25. d.tubeType = QString("tubeType%1").arg(i);
  26. d.tubeNumber = i+100;
  27. d.rackNumber = i+10;
  28. d.beginTime = QDateTime::currentDateTime().toTime_t();
  29. d.processed = 50+i;
  30. d.taskOwner = QString("owner%1").arg(i);
  31. model->addData(d);
  32. }
    /...

继承QAbstractTableModel QStyledItemDelegate实现自定义表格,添加进度条和选中框。的更多相关文章

  1. Android零基础入门第52节:自定义酷炫进度条

    原文:Android零基础入门第52节:自定义酷炫进度条 Android系统默认的ProgressBar往往都不能满足实际开发需要,一般都会开发者自定义ProgressBar. 在Android开发中 ...

  2. struts2上传文件添加进度条

    给文件上传添加进度条,整了两天终于成功了. 想要添加一个上传的进度条,通过分析,应该是需要不断的去访问服务器,询问上传文件的大小.通过已上传文件的大小, 和上传文件的总长度来评估上传的进度. 实现监听 ...

  3. QTableView 添加进度条

    记录一下QTableView添加进度条 例子很小,仅供学习 使用QItemDelegate做的实现 有自动更新进度 要在.pro文件里添加 CONFIG += c++ ProgressBarDeleg ...

  4. iOS-仿支付宝加载web网页添加进度条

    代码地址如下:http://www.demodashi.com/demo/11727.html 目前市场上APP常会嵌入不少的h5页面,参照支付宝显示web页面的方式, 做了一个导航栏下的加载进度条. ...

  5. Android自定义圆角矩形进度条2

    效果图: 或 方法讲解: (1)invalidate()方法 invalidate()是用来刷新View的,必须是在UI线程中进行工作.比如在修改某个view的显示时, 调用invalidate()才 ...

  6. Android简易实战教程--第十七话《自定义彩色环形进度条》

    转载请注明出处:http://blog.csdn.net/qq_32059827/article/details/52203533   点击打开链接 在Android初级教程里面,介绍了shape用法 ...

  7. EasyUI添加进度条

    EasyUI添加进度条 添加进度条重点只有一个,如何合理安排进度刷新与异步调用逻辑,假如我们在javascript代码中通过ajax或者第三方框架dwr等对远程服务进行异步调用,实现进度条就需要做到以 ...

  8. c#devexpress GridContorl添加进度条

    demo 的实现图 下边是步骤和代码 1定义 时钟事件,定时的增加进度条的增量. 2:  添加进度条 3;定义字段属性 using System; using System.Collections.G ...

  9. iOS WKWebView添加进度条02

    之前写了一个是关于webview添加进度条的,现在补一个WKWebView进度条. //添加一个全局属性 @property(nonatomic,strong)CALayer *progresslay ...

  10. Android:webView加载h5网页视频,播放不了,以及横屏全屏的问题和实现自定义加载进度条的效果

    1.webView加载h5网页视频,播放不了,android3.0之后要在menifest添加硬件加速的属性 android:hardwareAccelerated="true". ...

随机推荐

  1. 关于Dockerfile的写法

    Dockerfile是用来自定义构建镜像的文件. Dockerfile: FROM nginx RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/ht ...

  2. mindxdl--common--http_handler.go

    // Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.// Package common this file ...

  3. Go语言核心36讲27

    在前面的文章中,我们一起学习了Go程序测试的基础知识和基本测试手法.这主要包括了Go程序测试的基本规则和主要流程.testing.T类型和testing.B类型的常用方法.go test命令的基本使用 ...

  4. Day17:稀疏数组的超细详解

    稀疏数组的超细详解 一个含有大量重复元素的二维数组,我们可以提取其有效元素,压缩空间,整合为一个稀疏数组. 例如一个五子棋棋盘,我们将棋盘看作为一个二维数组,没有棋子的位置为0:黑棋为1:白棋为2: ...

  5. IDEA项目下out与target目录的区别详解

    IDEA项目下out与target目录的区别详解 一.目录主要区别: out存放的是该项目下所有Module(模块)的编译结果. target存放的是单个Module的编译结果. 二.目录详解 out ...

  6. PGL图学习之项目实践(UniMP算法实现论文节点分类、新冠疫苗项目实战,助力疫情)[系列九]

    原项目链接:https://aistudio.baidu.com/aistudio/projectdetail/5100049?contributionType=1 1.图学习技术与应用 图是一个复杂 ...

  7. mq中如何保证消息的顺序性

    先说结论 不建议在mq当中使用消息的投递顺序来保证消息的顺序一致性 反思为什么需要保留消息的顺序性 日常思维中,顺序大部分情况会和时间关联起来,即时间的先后表示事件的顺序关系.消息队列中的若干消息如果 ...

  8. 干电池升压5V,功耗比较低

    干电池升压5V,功耗10uA PW5100干电池升压5V芯片 输出电容: 所以为了减小输出的纹波,需要比较大的输出电容值.但是输出电容过大,就会使得系统的 反应时间过慢,成本也会增加.所以建议使用一个 ...

  9. MySQL的安装与配置,图形化软件安装,以及IDEA上的配置操作

    1. MySQL安装详细教程 注意:本次安装例为随笔发布时最新的8.0.31版本教程,由于您所希望安装的版本不同可能会导致一些问题,请谅解. 进入官网下载界面 https://www.mysql.co ...

  10. STM32与PS2的无线通信和相关函数介绍

    PS2采用SPI通信协议 源码和参考文件获取:https://github.com/Sound-Sleep/PS2_Based_On_STM32 接收器接口 DI:手柄->主机,时钟的下降沿传送 ...