1 写在前面的话
我们在之前写的《QT(7)-初识委托》文章末尾提到,“使用一个类继承QStyledItemDelegate实现常用的控件委托,在使用时可以直接调用接口,灵活实现各种委托”。我们接下来几篇文章将先详细讲解各个控件的委托,最后整理成一个类,并分享源码。如果大家感兴趣,可以点个关注,后面我们一起学习!
讲解比较详细,大家可以跟着一步一步做,自己就可以实现了。
2 需要用到的部分知识
《QT(3)-QTableView》
《QT(4)-QAbstractItemView》
《QT(6)-QStandardItemModel》
《QT(7)-初识委托》
3 同系列文章
QT中级(1)QTableView自定义委托(一)实现QSpinBox、QDoubleSpinBox委托
4 实现QProgressBar委托
进度条一般都是要一直显示在QTableView上,所以要实现QProgressBar委托,就要重新实现paint函数。
4.1 第一步
文件结构如下:
在设计师界面拖拽一个tableview到MainWindow
中,并对其进行初始化。
需要主要的是 void initTable(...);
这个函数是我在经常使用QTableView时通用的设置,不仅可以在这个项目使用,也可以在其他项目中使用
代码如下:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>class QStandardItemModel;
class QTableView;QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();void init();//设置表格void initTable(QTableView *tableView,int rowHeight = 25,bool Editable=false,bool isSorting = false,bool verticalHeadVisible=false,bool isLastTensile = true,bool isShowGrid = true);private:Ui::MainWindow *ui;QStandardItemModel *model;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"#include <QStandardItemModel>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);this->initTable(ui->tableView,27,true);this->init();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::init()
{QStringList columnNames;columnNames<<"QSpinBox"<<"QComboBox"<<"QCheckBox"<<"QProgressBar"<<"···";model = new QStandardItemModel;model->setRowCount(10);model->setHorizontalHeaderLabels(columnNames);ui->tableView->setModel(model);}void MainWindow::initTable(QTableView *tableView,int rowHeight,bool Editable,bool isSorting,bool verticalHeadVisible,bool isLastTensile,bool isShowGrid)
{/*设置样式*/tableView->setProperty("model",true);/*设置默认行高*/tableView->verticalHeader()->setDefaultSectionSize(rowHeight);/*设置交替行颜色--允许交替行颜色*/tableView->setAlternatingRowColors(true);/*设置水平/垂直滚动模式--一次滚动一个项目*/tableView->setHorizontalScrollMode(QAbstractItemView::ScrollPerItem);tableView->setVerticalScrollMode(QAbstractItemView::ScrollPerItem);/*设置选择行为--每次选择只有一整行*/tableView->setSelectionBehavior(QAbstractItemView::SelectRows);/*设置拖放行为--不允许拖放*/tableView->setDragDropMode(QAbstractItemView::NoDragDrop);/*设置选择模式--只能选择一个项目*/tableView->setSelectionMode(QAbstractItemView::SingleSelection);/*设置Tab导航键--允许使用Tab键导航,shift+tab反向导航*/tableView->setTabKeyNavigation(true);/*设置是否自动换行--取消自动换行*/tableView->setWordWrap(false);/*设置文本省略模式--省略号不会出现在文本中*/tableView->setTextElideMode(Qt::ElideNone);/*设置左上角全选按钮--禁用*/tableView->setCornerButtonEnabled(false);/*设置是否支持表头排序--应该和表头是否可以单击保持一致*/tableView->setSortingEnabled(isSorting);/*设置是否显示网格线*/tableView->setShowGrid(isShowGrid);/*设置垂直表头是否可见*/tableView->verticalHeader()->setVisible(verticalHeadVisible);/*设置选中一行表头是否加粗--不加粗*/tableView->horizontalHeader()->setHighlightSections(false);/*设置最后一行是否拉伸填充*/tableView->horizontalHeader()->setStretchLastSection(isLastTensile);/*设置行标题最小宽度尺寸*/tableView->horizontalHeader()->setMinimumSectionSize(0);/*设置行标题最小高度*/tableView->horizontalHeader()->setFixedHeight(rowHeight);/*设置表头是否可以单击--不可单击*/
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))tableView->horizontalHeader()->setSectionsClickable(isSorting);
#elsetableView->horizontalHeader()->setClickable(false);
#endif/*是否可编辑*/if(Editable){tableView->setEditTriggers(QAbstractItemView::CurrentChanged|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed);}else{tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);}
}
4.2 第二步
- 我们首先创建一个类
Delegate
继承QStyledItemDelegate
,同时定义paint函数
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
这四个函数的作用以及意义,详见:《QT(7)-初识委托》这里不在赘述。
- 创建一些 QSpinBox相关参数,并创建相应参数的外部设置接口
/*QProgressBar设置相关参数函数*/void setPgBarRange(const int min,const int max);void setPgBarTextVisible(bool isTextVisible);void setPgBarAlignment(Qt::Alignment pgbarAlignment);void setInvertedAppearance(bool invertedAppearance);/*QProgressBar相关参数*/int pgbarMax;int pgbarMin;Qt::Alignment pgbarAlignment;bool isTextVisible;bool invertedAppearance;QProgressBar *pgBar;
这里我定义了很多参数,实际应用的时候有些参数并用不到,大家根据需求定义。
- 创建给这些参数初始化的函
init()
void Delegate::init()
{pgBar = new QProgressBar;pgbarMax = 100;pgbarMin = 0;pgbarAlignment = Qt::AlignCenter;isTextVisible = true;invertedAppearance = false;
}
4.3 第三步
下面我们逐个实现paint函数
void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{if(index.column() == 3){//获得视图中的值int value = index.model()->data(index,Qt::DisplayRole).toInt();//创建包含QProgressBar样式信息类QStyleOptionProgressBar soPgbar;//使用我们创建的pgBar初始化soPgbarsoPgbar.initFrom(pgBar);//设置最大值和最小值soPgbar.maximum = pgbarMax;soPgbar.minimum = pgbarMin;//设置进度条值soPgbar.progress = value;//设置状态soPgbar.state |= QStyle::State_Enabled;soPgbar.state |= QStyle::State_Horizontal;//设置位置和大小soPgbar.rect = option.rect;//设置文本soPgbar.text = QString("%1%").arg(value);//设置文本是否可见soPgbar.textVisible = isTextVisible;//设置文本居中soPgbar.textAlignment = pgbarAlignment;//设置进度条的进度方向soPgbar.invertedAppearance = invertedAppearance;//绘制QApplication::style()->drawControl(QStyle::CE_ProgressBar,&soPgbar,painter,pgBar);}//ifelse{QStyledItemDelegate::paint(painter,option,index);}
}
4.4 最后一步
我们需要在mainwindow.cpp
中的init()
调用delegate
类实现委托。我们将QTableView的第一列设置为委托:
更新mainwindow.cpp
中的init()
函数
void MainWindow::init()
{QStringList columnNames;columnNames<<"QSpinBox"<<"QComboBox"<<"QCheckBox"<<"QProgressBar"<<"···";model = new QStandardItemModel;model->setRowCount(10);model->setHorizontalHeaderLabels(columnNames);ui->tableView->setModel(model);Delegate *pgbarDelegate = new Delegate;ui->tableView->setItemDelegateForColumn(3,pgbarDelegate);
}
4.5 运行效果
5 源码
- 有钱人通道:电梯
- 白嫖通道:评论下方留下你的邮箱或者私信我
都看到这里了,赏个关注吧!