同系列文章 QT中級(1)QTableView自定義委托(一)實現QSpinBox、QDoubleSpinBox委托 QT中級(2)QTableView自定義委托(二)實現QProgressBar委托 QT中級(3)QTableView自定義委托(三)實現QCheckBox委托並且將QCheckBo ...
同系列文章
QT中級(1)QTableView自定義委托(一)實現QSpinBox、QDoubleSpinBox委托
QT中級(2)QTableView自定義委托(二)實現QProgressBar委托
QT中級(3)QTableView自定義委托(三)實現QCheckBox委托並且將QCheckBox居中
QT中級(4)QTableView自定義委托(四)實現QDateTimeEdit、QDateEdit控制項
QT高級(1)QTableView自定義委托集合,一個類實現若幹委托
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_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
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);
#else
tableView->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初始化soPgbar
soPgbar.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);
}//if
else
{
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 源碼
都看到這裡了,賞個關註吧!