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

-自定义数据

itemdata.h

#ifndef ITEMDATA_H
#define ITEMDATA_H
#include <QMetaType>
#include <QString>
#include <QDebug> typedef enum{
level_0 = 0,
level_1,
level_2,
level_3,
level_4,
level_5,
level_6,
level_7,
level_8,
level_9,
level_none,
} Priority; typedef enum{
state_0 = 0,
state_1,
state_2,
state_3,
state_4,
state_5,
state_6,
state_7,
state_8,
state_9,
}State; struct Data{
Priority priority;
State taskState;
QString taskCode;
QString taskName;
QString taskType;
QString tubeType;
int tubeNumber;
int rackNumber;
int beginTime;
int processed; //[0-100]
QString taskOwner;
bool select = false;
}; Q_DECLARE_METATYPE(Data) #endif // ITEMDATA_H

-继承QAbstractTableModel自定义数据

mytablemodel.h

#ifndef MYTABLEMODEL_H
#define MYTABLEMODEL_H
#include<QAbstractTableModel>
#include <QList> #include "itemdata.h" class myTableModel:public QAbstractTableModel
{
Q_OBJECT
public:
myTableModel(QAbstractTableModel *parent = 0);
~myTableModel();
QVariant data(const QModelIndex &index, int role) const;// 重写,用于返回数据
int rowCount(const QModelIndex &parent = QModelIndex()) const; // 重写, 反回行数
int columnCount(const QModelIndex &parent = QModelIndex()) const;// 重写,返回列数
QVariant headerData(int section, Qt::Orientation, int role)const;// 重写, 返回列标题
Qt::ItemFlags flags(const QModelIndex &index) const; // 重写, 每一项的操作标识
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);// 重写, 设置数据 void addData(Data data);// 添加模型数据 private:
QStringList _roleNames;
QList<Data> _dataList;
}; #endif // MYTABLEMODEL_H
#include "mytablemodel.h"

myTableModel::myTableModel(QAbstractTableModel *parent):QAbstractTableModel(parent),
_roleNames({"priority","taskState","taskCode","taskName","taskType","tubeType","tubeNumber","rackNumber","beginTime","processed","taskOwner","select"}){ } myTableModel::~myTableModel(){ } QVariant myTableModel::data(const QModelIndex &index, int role) const{
QVariant v;
switch (role - (Qt::UserRole+1)) {// 自定义角色从Qt::UserRole + 1开始
case 0:
v = QVariant(_dataList[index.row()].priority);
break;
case 1:
v = QVariant(_dataList[index.row()].taskState);
break;
case 2:
v = QVariant(_dataList[index.row()].taskCode);
break;
case 3:
v = QVariant(_dataList[index.row()].taskName);
break;
case 4:
v = QVariant(_dataList[index.row()].taskType);
break;
case 5:
v = QVariant(_dataList[index.row()].tubeType);
break;
case 6:
v = QVariant(_dataList[index.row()].tubeNumber);
break;
case 7:
v = QVariant(_dataList[index.row()].rackNumber);
break;
case 8:
v = QVariant(_dataList[index.row()].beginTime);
break;
case 9:
v = QVariant(_dataList[index.row()].processed);
break;
case 10:
v = QVariant(_dataList[index.row()].taskOwner);
break;
case 11:
v= QVariant(_dataList[index.row()].select);
break;
}
return v;
} int myTableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return _dataList.size();// 行数
} int myTableModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return _roleNames.size();//列数
} //QHash<int, QByteArray> myTableModel::roleNames() const
//{
// QHash<int,QByteArray> roleName;
// for(int i = 0; i < _roleNames.size(); ++i){
// roleName.insert(Qt::UserRole+1+i,_roleNames[i].toLocal8Bit());
// }
// return roleName;
//} QVariant myTableModel::headerData(int section, Qt::Orientation orientation, int role)const{
if(role == Qt::DisplayRole && orientation == Qt::Orientation::Horizontal){ //返回列标题
QString sectionName;
switch (section) {
case 0:
sectionName = tr("优先级");
break;
case 1:
sectionName = tr("状态");
break;
case 2:
sectionName = tr("编码");
break;
case 3:
sectionName = tr("名称");
break;
case 4:
sectionName = tr("类型");
break;
case 5:
sectionName = tr("冻存管型号");
break;
case 6:
sectionName = tr("管数量");
break;
case 7:
sectionName = tr("盒数量");
break;
case 8:
sectionName = tr("开始时间");
break;
case 9:
sectionName = tr("进度");
break;
case 10:
sectionName = tr("发起人");
break;
case 11:
sectionName = tr("选中");
break; }
return sectionName;
}
return QVariant();
} void myTableModel::addData(Data data){
beginInsertRows(QModelIndex(),_dataList.count(),_dataList.count()); //添加数据之前进行通知并告知添加到什么位置
_dataList.push_back(data);
endInsertRows();
} Qt::ItemFlags myTableModel::flags(const QModelIndex &index) const {
if(!index.isValid()){
return Qt::NoItemFlags;
}
Qt::ItemFlags flags;
flags = QAbstractItemModel::flags(index);
if(index.column() == 11){
flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable|Qt::ItemIsUserCheckable;// 选项框设置为可选中
} else { flags |= Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
}
return flags;
}
bool myTableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
if(role == Qt::UserRole + 1 + 11){// 设置选项框数据true or false
QVector<int> changeRoles;
changeRoles.push_back(Qt::UserRole + 1 + 11);
for(QList<Data>::iterator it = _dataList.begin(); it != _dataList.end(); ++it){
if((*it).taskCode == index.data(Qt::UserRole +1 + 2).toString()){ // 根据taskCode定位选中的数据行
(*it).select = value.toBool();
}
}
emit dataChanged(index,index,changeRoles);
return true;
} else{
return QAbstractTableModel::setData(index, index,role); // 调用默认父类默认实现
}
}

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

myitemdelegate.h

#ifndef MYITEMDELEGATE_H
#define MYITEMDELEGATE_H
#include <QStyledItemDelegate>
#include <QPainter>
#include <QStyleOptionViewItem>
#include <QRect>
#include <QPainterPath>
#include <QDate>
#include <QTime>
#include <QApplication> #include "itemdata.h" class myItemDelegate:public QStyledItemDelegate
{
Q_OBJECT
public:
myItemDelegate(QStyledItemDelegate * parent = 0);
~myItemDelegate(); void paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const; // 重写,绘制每一项
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;//重写, 返回项尺寸
bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index);// 重写,处理项事件
QRect checkBoxRect(const QStyleOptionViewItem &viewItemStyleOptions) const;//返回选中框尺寸 }; #endif // MYITEMDELEGATE_H
#include "myitemdelegate.h"
#include <QMouseEvent> myItemDelegate::myItemDelegate(QStyledItemDelegate *parent):QStyledItemDelegate(parent)
{ } myItemDelegate::~myItemDelegate(){ } void myItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{
if(index.isValid()){
painter->save();
int column = index.column();
QVariant v = index.data(column + (Qt::UserRole+1)); //获取数据
// painter->drawRect(option.rect); QStyleOptionViewItem viewOption(option);
if(0 == column){
Priority priority = (Priority)v.toInt();
painter->drawText(option.rect, Qt::AlignCenter, QString::number(priority));
}else if(1 == column){
State state = (State)v.toInt();
painter->drawText(option.rect, Qt::AlignCenter, QString::number(state));
}
else if(2 == column){
QString taskCode = v.toString();
painter->drawText(option.rect, Qt::AlignCenter,taskCode);
}
else if(3 == column){
QString taskName = v.toString();
painter->drawText(option.rect, Qt::AlignCenter,taskName);
}
else if(4== column){
QString taskType = v.toString();
painter->drawText(option.rect, Qt::AlignCenter,taskType);
}
else if(5 == column){
QString tubeType = v.toString();
painter->drawText(option.rect, Qt::AlignCenter,tubeType);
}
else if(6 == column){
int tubeNumber = v.toInt();
painter->drawText(option.rect, Qt::AlignCenter, QString::number(tubeNumber));
}
else if(7 == column){
int rackNumber = v.toUInt();
painter->drawText(option.rect, Qt::AlignCenter, QString::number(rackNumber));
}
else if(8== column){
int beginTime = v.toInt();
QRect timeRect = QRect(option.rect.left(),option.rect.top(),option.rect.width(),option.rect.height()/2);
QRect dateRect = QRect(option.rect.left(),option.rect.top()+(option.rect.height()/2),option.rect.width(),option.rect.height()/2);
painter->drawText(timeRect,Qt::AlignCenter,QDateTime::fromSecsSinceEpoch(beginTime).toString("hh:mm:ss"));
painter->drawText(dateRect,Qt::AlignCenter,QDateTime::fromSecsSinceEpoch(beginTime).toString("yyyy-MM-dd"));
}
else if(9 == column){// 绘制进度条
int processed = v.toInt(); QStyleOptionProgressBar *processBar = new QStyleOptionProgressBar();
processBar->rect = QRect(option.rect.left(),option.rect.top()+(option.rect.height()/3),option.rect.width(),option.rect.height()/3);
processBar->minimum = 0;
processBar->maximum = 100;
processBar->progress = processed;
processBar->text = QString::number(processed)+"%";
processBar->textAlignment = Qt::AlignBottom;
processBar->textVisible = true;
QApplication::style()->drawControl(QStyle::CE_ProgressBar, processBar, painter);
// painter->drawText(option.rect, Qt::AlignCenter, QString::number(processed));
}
else if(10 == column){
QString taskOwner = v.toString();
painter->drawText(option.rect, Qt::AlignCenter,taskOwner);
}
else if(11 == column){ // 绘制选项框
bool checked = v.toBool();
QStyleOptionButton checkButton;
checkButton.state |= QStyle::State_Enabled;
checkButton.state |= checked ? QStyle::State_On : QStyle::State_Off;// 根据模型值设定是否选中
checkButton.rect = checkBoxRect(option);
QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkButton, painter);
}
painter->restore(); }
} QSize myItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const{
qDebug()<< option.rect.width()<< option.rect.height();
//return QSize(option.rect.size());
//return QSize(40,60);
return QSize(option.rect.width(), 200);
}
QRect myItemDelegate::checkBoxRect(const QStyleOptionViewItem &viewItemStyleOptions) const {
QStyleOptionButton checkBoxStyleOption;
QRect checkBoxRect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkBoxStyleOption);
QPoint checkBoxPoint(viewItemStyleOptions.rect.x() + (viewItemStyleOptions.rect.width()- checkBoxRect.width())/2,
viewItemStyleOptions.rect.y() + (viewItemStyleOptions.rect.height()- checkBoxRect.height())/2);
return QRect(checkBoxPoint, checkBoxRect.size());
}
bool myItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) {
if(index.column() == 11){
if(event->type() == QEvent::MouseButtonRelease){
QMouseEvent *mouseEvent = (QMouseEvent*)event;
if(mouseEvent->button() == Qt::LeftButton && checkBoxRect(option).contains(mouseEvent->pos())){
bool checked = index.data(Qt::UserRole + 1 + 11).toBool();
return model->setData(index, !checked, Qt::UserRole + 1 + 11);// 单击选中框设置相反的选中状态
}
}
}
return QStyledItemDelegate::editorEvent(event, model, option, index); //其余事件调用默认实现
}

-测试

.../
QSortFilterProxyModel *sortModel = new QSortFilterProxyModel();
myTableModel *model = new myTableModel();
myItemDelegate *itemDelegate = new myItemDelegate();
ui->tableView->setItemDelegate(itemDelegate);
sortModel->setSourceModel(model);
sortModel->setDynamicSortFilter(true);
sortModel->setSortRole(Qt::UserRole+1); //按照权限排序
ui->tableView->setSortingEnabled(true);
ui->tableView->setModel(sortModel); ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView->setSelectionMode ( QAbstractItemView::SingleSelection);
// ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->tableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
ui->tableView->resizeColumnsToContents();
ui->tableView->setShowGrid(false);
for(int i = 0 ;i < 10 ; ++i){
Data d;
d.priority = static_cast<Priority>(i);
d.taskState = static_cast<State>(9-i);
d.taskCode = QString("taskCode%1").arg(i);
d.taskName = QString("taskName%1").arg(i);
d.taskType = QString("taskType%1").arg(i);
d.tubeType = QString("tubeType%1").arg(i);
d.tubeNumber = i+100;
d.rackNumber = i+10;
d.beginTime = QDateTime::currentDateTime().toTime_t();
d.processed = 50+i;
d.taskOwner = QString("owner%1").arg(i);
model->addData(d);
}
/...

继承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. JS 可编辑表格的实现

    1.实现效果 用户点击语文,数学,英语部分的单元格,可以实现分数的编辑,总分也会随之变化.先看下效果,如图: 2.设计思路 先通过HTML5+CSS3绘制表格,添加input的样式和err提示动画. ...

  2. tomcat报Address localhost:1099 is already in use

    idea运行tomcat报Address localhost:1099 is already in use 解决方案: 电脑桌面->ctrl+shift+esc 打开任务管理器,选择详细信息,找 ...

  3. 2022春每日一题:Day 23

    题目:Piotr's Ants 蚂蚁转头走,其实可以看做他们交换灵魂后接着往前走,同样发现,既然他们的速度相同,那么在数轴上相对位置不会改变(碰面会改变方向),那就好办了. 先把初始状态排序,id都记 ...

  4. Kubernetes_k8s持久化存储(亲测可用)

    一.前言 新建具有两个节点的k8s集群,主节点(master节点/m节点)的ip地址是192.168.100.150,从节点(w1节点)的ip地址是192.168.100.151. 本文操作如何将po ...

  5. services资源+pod详解

    services资源+pod详解 一.Service 虽然每个Pod都会分配一个单独的Pod IP,然而却存在如下两问题: Pod IP 会随着Pod的重建产生变化 Pod IP 仅仅是集群内可见的虚 ...

  6. 复现MySQL的索引选择失误以及通过OPTIMIZER_TRACE分析过程

    复现MySQL的索引选择失误以及通过OPTIMIZER_TRACE分析过程 验证环境:MySQL 5.7.39 windows-pc 一.构造数据(生成150万数据) 构建一张账户表,带有一级部门id ...

  7. 【面试题总结】Java并发-多线程、JUC详述(思维导图)

    〇.整体目录 一.多线程 1.实现方式 2.内存图 3.线程状态 4.实现线程同步 5.并发编程 二.JUC 1.概述与volatile关键字 2.ThreadLocal类 3.CAS方法 4.ato ...

  8. NCTF2022 - pwn 部分 wp

    总的来说我出的几题不是很难,主要是想把自己感觉有意思的一些东西分享给大家. ezlogin 程序设计周大作业稍加改编出的题目.洞在Tea里,有个数组越界写,为了避开\x00截断,我给了*可以对其进行替 ...

  9. NavigationDuplicated Navigating to current location (“/XXX”) is not allowed

    导航不允许导航到当前位置https://stackoverflow.com/questions/57837758/navigationduplicated-navigating-to-current- ...

  10. Java中将 int[] 数组 转换为 List(ArrayList)

    前言 说起数组转换成 ArrayList,很多同学第一反应就是遍历数组,将元素逐个添加到 ArrayList 中,但是这个看着就lower,一般不会这么答. 所以马上就会想到Arrays工具类的 as ...