参考:
QTableView表格控件代理详解
https://blog.csdn.net/u010031316/article/details/120366295
运行环境:WIN10,VS2022,QT6.3
创建的QtWidgetApplication项目,解决方案目录及main主函数如下图:
qrc资源文件中就放了几个从阿里巴巴矢量图库下载的几张图:
ui中就部署了一个qtablewidget,如图所示:
分模块代码
ComboBox委托:
// ComboBox委托classComboBoxDelegate:publicQItemDelegate{
Q_OBJECT
public:ComboBoxDelegate(QObject* parent =0):QItemDelegate(parent){}// 开始编辑状态
QWidget*createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const{
QComboBox* editor =newQComboBox(parent);//if (flag == false)//{// return editor;//}if(m_list.isEmpty())returnNULL;
QStandardItemModel* model =newQStandardItemModel(editor);for(int i =0; i < m_list.count(); i++){
QStandardItem* item =newQStandardItem(m_list.at(i));
item->setTextAlignment(Qt::AlignCenter);
item->setToolTip(ip_list.at(i));
item->setData(ip_list.at(i), Qt::UserRole);
model->setItem(i, item);}
editor->setModel(model);//editor->setCurrentIndex(0);
editor->setCurrentText(index.data(Qt::EditRole).toString());return editor;}// 正在编辑状态voidsetEditorData(QWidget* editor,const QModelIndex& index)const{
QString text = index.model()->data(index, Qt::EditRole).toString();
QComboBox* comboBox =static_cast<QComboBox*>(editor);connect(comboBox,&QComboBox::currentTextChanged,this,[=](const QString& text){// 用于置脏数据来着 可以根据需求灵活修改//emit ComboTextChanged(index, text);});
comboBox->setCurrentText(text);}// 退出编辑状态voidsetModelData(QWidget* editor, QAbstractItemModel* model,const QModelIndex& index)const{//if (flag == false)// return;
QComboBox* comboBox =static_cast<QComboBox*>(editor);
QString text = comboBox->currentText();
QString ip;
QStandardItemModel* comb_model =dynamic_cast<QStandardItemModel*>(comboBox->model());if(comb_model){
QStandardItem* item = comb_model->item(comboBox->currentIndex());
ip = item->data(Qt::UserRole).toString();}if(text != index.data().toString()){//model->blockSignals(true);
model->setData(index, ip, Qt::UserRole);
model->setData(index, text, Qt::EditRole);//model->setData(index, "", Qt::UserRole+1);//model->blockSignals(false);}//emit ComboTextChanged(index, text);//emit sigStudentSeatChange();}voidupdateEditorGeometry(QWidget* editor,const QStyleOptionViewItem& option,const QModelIndex& index)const{
editor->setGeometry(option.rect);}// 参数数量可以根据需求灵活修改voidsetMenuList(QStringList _site_name_list, QStringList _site_ip_list){
m_list = _site_name_list;
ip_list = _site_ip_list;}// void setSignalFlag(bool _flag)// {// flag = _flag;// }
signals:// 可以根据需求添加自定义信号进行处理//void ComboTextChanged(const QModelIndex& index, const QString text)const;//void sigStudentSeatChange(const QTableWidgetItem * _item)const;private:
QStringList m_list;
QStringList ip_list;//bool flag; // true为可编辑状体 false为不可编辑状态};
状态代理:
// 状态代理classStatusDelegate:publicQStyledItemDelegate{
Q_OBJECT
public:StatusDelegate(QObject* parent =nullptr){};~StatusDelegate(){}protected:voidpaint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const;booleditorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index);private:
QString m_text;};
状态代理实现cpp:
voidStatusDelegate::paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const{constbool enabled = option.state & QStyle::State_Enabled;constbool active = option.state & QStyle::State_Active;constbool selected = option.state & QStyle::State_Selected;if(enabled && active && selected)
painter->fillRect(option.rect, option.palette.highlight());if(enabled && selected &&!active){
painter->fillRect(option.rect, option.palette.color(QPalette::Inactive, QPalette::Highlight));}int height = option.rect.height();int width = option.rect.width();int m_x = option.rect.x()+ width /4-5;int m_y = option.rect.y()+ height /2-5;
QString site_status = index.data(Qt::UserRole).toString();
painter->save();//QColor brush = Qt::transparent;if(index.data(Qt::UserRole).toString()=="关于"){//brush = QColor(6, 176, 37);
QPixmap pixmap =QPixmap(8,8);
pixmap.load(QString(":/QtDelegateTest/res/关于.png"));
painter->drawPixmap(m_x -10, m_y, pixmap);
painter->drawText(m_x, option.rect.y(), width *3/4, height, Qt::AlignCenter, site_status);}elseif(index.data(Qt::UserRole).toString()=="设置"){//brush = QColor(177, 177, 177);
QPixmap pixmap =QPixmap(8,8);
pixmap.load(QString(":/QtDelegateTest/res/设置.png"));
painter->drawPixmap(m_x -10, m_y, pixmap);
painter->drawText(m_x, option.rect.y(), width *3/4, height, Qt::AlignCenter, site_status);}elseif(index.data(Qt::UserRole).toString()=="退出"){//brush = QColor(255, 0, 0);
QPixmap pixmap =QPixmap(8,8);
pixmap.load(QString(":/QtDelegateTest/res/退出.png"));
painter->drawPixmap(m_x -10, m_y, pixmap);
painter->drawText(m_x, option.rect.y(), width *3/4, height, Qt::AlignCenter, site_status);}
painter->restore();}boolStatusDelegate::editorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index){returnQStyledItemDelegate::editorEvent(event, model, option, index);}
只读代理:
//只读代理classReadOnlyDelegate:publicQItemDelegate{
Q_OBJECT
public:ReadOnlyDelegate(QObject* parent =0):QItemDelegate(parent){}
QWidget*createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const{returnnullptr;}};
spinBox委托:
//spinBox委托classSpinBoxDelegate:publicQItemDelegate{
Q_OBJECT
public:SpinBoxDelegate(QObject* parent =0):QItemDelegate(parent){ m_minimum =0; m_maxinum =0; m_singleStep =0;}
QWidget*createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const{
QSpinBox* editor =newQSpinBox(parent);
editor->setMinimum(m_minimum);
editor->setMaximum(m_maxinum);
editor->setSingleStep(m_singleStep);return editor;}voidsetEditorData(QWidget* editor,const QModelIndex& index)const{int value = index.model()->data(index, Qt::EditRole).toInt();
QSpinBox* spinbox =static_cast<QSpinBox*>(editor);// 此处注释部分为Qt5实现方法 为了解决函数重载的信号绑定问题 Qt升级后将函数重载的函数更改了名字如下所示connect(spinbox,/*static_cast<void (QSpinBox::*)(const QString&)>*/(&QSpinBox::/*valueChanged*/textChanged),this,[=](const QString& value){
emit SpinBoxValueChanged(index, value);});
spinbox->setValue(value);}voidsetModelData(QWidget* editor, QAbstractItemModel* model,const QModelIndex& index)const{
QSpinBox* spinBox =static_cast<QSpinBox*>(editor);int value = spinBox->value();if(model->data(index, Qt::EditRole).toInt()!= value)
model->setData(index, value, Qt::EditRole);}voidupdateEditorGeometry(QWidget* editor,const QStyleOptionViewItem& option,const QModelIndex& index)const{
editor->setGeometry(option.rect);}voidsetSpinBoxProperty(double minimum,double maxinum,double singleStep){
m_minimum =(int)minimum;
m_maxinum =(int)maxinum;
m_singleStep =(int)singleStep;}
signals:voidSpinBoxValueChanged(const QModelIndex& index,const QString& value)const;private:int m_minimum;// 最小值int m_maxinum;// 最大值int m_singleStep;// 每步调整大小};
DoubleSpinBox委托:
// DoubleSpinBox委托classDoubleSpinBoxDelegate:publicQItemDelegate{
Q_OBJECT
public:DoubleSpinBoxDelegate(QObject* parent =0):QItemDelegate(parent){ m_minimum =0; m_maxinum =0; m_singleStep =0; m_decimals =0;}
QWidget*createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const{
QDoubleSpinBox* editor =newQDoubleSpinBox(parent);
editor->setMinimum(m_minimum);
editor->setMaximum(m_maxinum);
editor->setSingleStep(m_singleStep);
editor->setDecimals(m_decimals);return editor;}voidsetEditorData(QWidget* editor,const QModelIndex& index)const{double value = index.model()->data(index, Qt::EditRole).toDouble();
QDoubleSpinBox* doubleSpinBox =static_cast<QDoubleSpinBox*>(editor);// 此处注释部分为Qt5实现方法 为了解决函数重载的信号绑定问题 Qt升级后将函数重载的函数更改了名字如下所示connect(doubleSpinBox,/*static_cast<void (QDoubleSpinBox::*)(const QString&)>*/(&QDoubleSpinBox::textChanged/*valueChanged*/),this,[=](const QString& value){
emit DoubleSpinBoxValueChanged(index, value);});
doubleSpinBox->setValue(value);}voidsetModelData(QWidget* editor, QAbstractItemModel* model,const QModelIndex& index)const{
QDoubleSpinBox* doubleSpinBox =static_cast<QDoubleSpinBox*>(editor);double value = doubleSpinBox->value();if(model->data(index, Qt::EditRole).toDouble()!= value)
model->setData(index,QString::number(value,'f', m_decimals), Qt::EditRole);}voidupdateEditorGeometry(QWidget* editor,const QStyleOptionViewItem& option,const QModelIndex& index)const{
editor->setGeometry(option.rect);}voidsetDoubleSpinBoxProperty(double minimum,double maxinum,double singleStep,int decimals){
m_minimum = minimum;
m_maxinum = maxinum;
m_singleStep = singleStep;// 每步调整多少
m_decimals = decimals;// 小数点后几位}
signals:voidDoubleSpinBoxValueChanged(const QModelIndex& index,const QString& value)const;private:double m_minimum;double m_maxinum;double m_singleStep;int m_decimals;};
checkBox勾选框代理:
// checkBox勾选框代理classCheckBoxDelegate:publicQStyledItemDelegate{
Q_OBJECT
public:CheckBoxDelegate(QObject* parent =0){}protected:virtual QSize sizeHint(const QStyleOptionViewItem& option,const QModelIndex& index)const;virtualvoidpaint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const;virtualbooleditorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index);
signals:voidCheckStateChanged(const QModelIndex& _index,int _state);};
checkBox勾选框代理实现cpp:
static QRect CheckBoxRect(const QStyleOptionViewItem& viewItemStyleOptions){
QStyleOptionButton checkBoxStyleOption;
QRect checkBoxRect =QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator,&checkBoxStyleOption);
QPoint checkBoxPoint(viewItemStyleOptions.rect.x()+ viewItemStyleOptions.rect.width()/2- checkBoxRect.width()/2,
viewItemStyleOptions.rect.y()+ viewItemStyleOptions.rect.height()/2- checkBoxRect.height()/2);returnQRect(checkBoxPoint, checkBoxRect.size());}
QSize CheckBoxDelegate::sizeHint(const QStyleOptionViewItem& option,const QModelIndex& index)const{
QStyleOptionViewItem opt = option;
QSize opt_size =QStyledItemDelegate::sizeHint(option, index);returnQSize(40,opt_size.height());}voidCheckBoxDelegate::paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const{//const bool enabled = option.state & QStyle::State_Enabled;//const bool active = option.state & QStyle::State_Active;//const bool selected = option.state & QStyle::State_Selected; 绘制原生背景//if (enabled && active && selected)// painter->fillRect(option.rect, option.palette.highlight());//if (enabled && selected && !active)// painter->fillRect(option.rect, option.palette.color(QPalette::Inactive, QPalette::Highlight));
QStyleOptionViewItem opt = option;bool checked = index.model()->data(index, Qt::DisplayRole).toBool();
QStyleOptionButton checkBoxStyleOption;
checkBoxStyleOption.state |= QStyle::State_Enabled;
checkBoxStyleOption.state |= checked ? QStyle::State_On : QStyle::State_Off;
checkBoxStyleOption.rect =CheckBoxRect(opt);
painter->setPen(Qt::black);
QRect text_rect =CheckBoxRect(opt);
text_rect.setWidth(text_rect.width()+20);
painter->drawText(text_rect, Qt::AlignRight | Qt::AlignVCenter,QString::number(index.row()+1));QApplication::style()->drawControl(QStyle::CE_CheckBox,&checkBoxStyleOption, painter);}boolCheckBoxDelegate::editorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index){if((event->type()== QEvent::MouseButtonRelease)||(event->type()== QEvent::MouseButtonDblClick)){
QMouseEvent* mouseEvent =static_cast<QMouseEvent*>(event);if(mouseEvent->button()!= Qt::LeftButton ||!CheckBoxRect(option).contains(mouseEvent->pos())){returntrue;}if(event->type()== QEvent::MouseButtonDblClick)returntrue;}elseif(event->type()== QEvent::KeyPress){if(static_cast<QKeyEvent*>(event)->key()!= Qt::Key_Space &&static_cast<QKeyEvent*>(event)->key()!= Qt::Key_Select)returnfalse;}elsereturnfalse;bool checked = index.model()->data(index, Qt::DisplayRole).toBool();if(checked ==false)
emit CheckStateChanged(index,1);else
emit CheckStateChanged(index,0);return model->setData(index,!checked, Qt::EditRole);}
表头添加checkBox:
// 表头添加checkBoxclassCCheckBoxHeaderView:publicQHeaderView{
Q_OBJECT
public:CCheckBoxHeaderView(int checkBoxColumnID, Qt::Orientation orientation, QWidget* parent);~CCheckBoxHeaderView(){}voidsetChecked(bool ischeck){
m_checkBoxIsOn = ischeck;updateSection(m_checkBoxColumnId);}voidsetSorted(bool isSort){
m_isSort = isSort;}protected:voidmousePressEvent(QMouseEvent* event);voidpaintSection(QPainter* painter,const QRect& rect,int logicalIndex)const;
signals:voidsig_AllChecked(bool);private:int m_checkBoxColumnId;bool m_checkBoxIsOn;bool m_isSort;};
表头添加checkBox实现cpp:
CCheckBoxHeaderView::CCheckBoxHeaderView(int checkBoxColumnId, Qt::Orientation orientation, QWidget* parent):QHeaderView(orientation, parent){
m_checkBoxColumnId = checkBoxColumnId;
m_checkBoxIsOn =false;
m_isSort =false;}voidCCheckBoxHeaderView::paintSection(QPainter* painter,const QRect& rect,int logicalIndex)const{
painter->save();QHeaderView::paintSection(painter, rect, logicalIndex);
painter->restore();if(logicalIndex == m_checkBoxColumnId){
QStyleOptionButton option;int width =3;for(int i =0; i < logicalIndex;++i)
width +=sectionSize(i);
option.rect =QRect(width,5,15,15);if(m_checkBoxIsOn)
option.state = QStyle::State_On;else
option.state = QStyle::State_Off;this->style()->drawControl(QStyle::CE_CheckBox,&option, painter);}}voidCCheckBoxHeaderView::mousePressEvent(QMouseEvent* event){int x = event->pos().x();int y = event->pos().y();if(visualIndexAt(event->pos().x())== m_checkBoxColumnId){//if (event->pos().x() >= 3 && event->pos().x() <= 18 && event->pos().y() >= 5 && event->pos().y() <= 20){this->setSectionsClickable(true);if(m_checkBoxIsOn)
m_checkBoxIsOn =false;else
m_checkBoxIsOn =true;this->updateSection(m_checkBoxColumnId);// 可以连接这个信号将下面所有checkbox状态改变
emit sig_AllChecked(m_checkBoxIsOn);}//else//{// this->setSectionsClickable(m_isSort);//}}else{this->setSectionsClickable(m_isSort);}QHeaderView::mousePressEvent(event);}
pushButton代理:
// pushButton代理classPushbuttonDelegate:publicQItemDelegate{
Q_OBJECT
public:PushbuttonDelegate(QObject* parent =0){}~PushbuttonDelegate(){}protected:voidpaint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const;booleditorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index);public:voidsetText(const QString& text);
signals:voidsig_buttonClicked(const QModelIndex& index,const QRect& rect);private:
QMap<QModelIndex, QStyleOptionButton*>m_pBtns;
QString m_text;};
pushButton代理实现cpp:
voidPushbuttonDelegate::setText(const QString& text){
m_text = text;}voidPushbuttonDelegate::paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const{constbool enabled = option.state & QStyle::State_Enabled;constbool active = option.state & QStyle::State_Active;constbool selected = option.state & QStyle::State_Selected;
QStyleOptionButton button;
button.rect = option.rect.adjusted(6,6,-6,-6);
button.text = m_text;
button.state = option.state;
button.iconSize =QSize(18,18);
QPixmap pixmap =QPixmap(8,8);
pixmap.load(QString(":/QtDelegateTest/res/设置.png"));
button.icon =QIcon(pixmap);//! \获取按钮状态bool pressed = index.data(Qt::UserRole +2).toBool();
button.state |= pressed ? QStyle::State_Sunken : QStyle::State_Raised;if(enabled && active && selected)
painter->fillRect(option.rect, option.palette.highlight());if(enabled && selected &&!active){
painter->fillRect(option.rect, option.palette.color(QPalette::Inactive, QPalette::Highlight));}
button.palette.setColor(QPalette::All, QPalette::ButtonText, painter->pen().color());QApplication::style()->drawControl(QStyle::CE_PushButton,&button, painter);}boolPushbuttonDelegate::editorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index){if(event->type()== QEvent::MouseButtonPress || event->type()== QEvent::MouseButtonRelease){if(QMouseEvent* mouseEvent =static_cast<QMouseEvent*>(event)){if(mouseEvent->button()== Qt::LeftButton){bool pressed =false;(event->type()== QEvent::MouseButtonPress)? pressed =true: pressed =false;
model->setData(index, pressed,/*Button_State_Sunken*/Qt::UserRole +2);if(event->type()== QEvent::MouseButtonPress){/* QString base_type = model->data(model->index(index.row(), index.column() - 2)).toString();*/
QStyleOption option_base = option;
QRect rect = option_base.rect;
emit sig_buttonClicked(index, rect);}returntrue;}}}returntrue;}
自定义组件:
// 自定义组件#include<QPushButton>#include<QFileDialog>#include<QHBoxLayout>#include<QObject>classCustomWidget:publicQWidget{
Q_OBJECT
public:explicitCustomWidget(QWidget* parent =0);~CustomWidget();public:voidSetText(QString _text);
QString GetText();private slots:voidSlotButtonclicked();private:
QLineEdit* le_path_;
QPushButton* pb_open_;
QString exe_path_;
QHBoxLayout* main_layout_;};// 自定义组合代理LineEdit+pushButton// 结合上面类进行使用 先创建qwidget再把widget放进代理类classCustomComDelegate:publicQItemDelegate{
Q_OBJECT
public:CustomComDelegate(QObject* parent =nullptr);~CustomComDelegate();
signals:voidSignalExePath(const QModelIndex _index, QString _exe_path)const;protected:virtualvoidpaint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const;virtual QSize sizeHint(const QStyleOptionViewItem& option,const QModelIndex& index)const;virtual QWidget*createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const;virtualvoidsetEditorData(QWidget* editor,const QModelIndex& index)const;virtualvoidsetModelData(QWidget* editor, QAbstractItemModel* model,const QModelIndex& index)const;};
自定义组件实现cpp:
// 自定义组合代理CustomWidget::CustomWidget(QWidget* parent /*= 0*/):QWidget(parent),exe_path_(){
pb_open_ =newQPushButton("...");
pb_open_->setFixedSize(25,25);
le_path_ =newQLineEdit();// 设置不可编辑
le_path_->setEnabled(true);
main_layout_ =newQHBoxLayout();
main_layout_->addWidget(le_path_);
main_layout_->addWidget(pb_open_);
main_layout_->setContentsMargins(0,0,0,0);
main_layout_->setSpacing(0);this->setLayout(main_layout_);connect(pb_open_,&QPushButton::clicked,this,&CustomWidget::SlotButtonclicked);}CustomWidget::~CustomWidget(){}voidCustomWidget::SlotButtonclicked(){
QString exe_path = le_path_->text();if(exe_path.isEmpty()){
exe_path =QFileDialog::getOpenFileName(this,"选择应用程序路径","C:/Users/admin/Desktop/","应用程序(*.exe)");}else{
exe_path =QFileDialog::getOpenFileName(this,"选择应用程序路径", exe_path,"应用程序(*.exe)");}if(!exe_path.isEmpty()){
le_path_->setText(exe_path);}}voidCustomWidget::SetText(QString _text){
le_path_->setText(_text);}
QString CustomWidget::GetText(){return le_path_->text();}// 自定义组合代理CustomComDelegate::CustomComDelegate(QObject* parent /*= nullptr*/):QItemDelegate(parent){}CustomComDelegate::~CustomComDelegate(){}voidCustomComDelegate::paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const{QItemDelegate::paint(painter, option, index);}
QSize CustomComDelegate::sizeHint(const QStyleOptionViewItem& option,const QModelIndex& index)const{returnQItemDelegate::sizeHint(option, index);}
QWidget*CustomComDelegate::createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const{
CustomWidget* custom_widget =newCustomWidget(parent);
custom_widget->installEventFilter(const_cast<CustomComDelegate*>(this));return custom_widget;}voidCustomComDelegate::setEditorData(QWidget* editor,const QModelIndex& index)const{
QString value = index.model()->data(index, Qt::DisplayRole).toString();
CustomWidget* custom_widget =qobject_cast<CustomWidget*>(editor);if(!value.isEmpty()){
custom_widget->SetText(value);}else{QItemDelegate::setEditorData(editor, index);}}voidCustomComDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,const QModelIndex& index)const{
CustomWidget* custom_widget =qobject_cast<CustomWidget*>(editor);// if (custom_widget->GetText().isEmpty()){// model->setData(index, "");// }// else{
model->setData(index, custom_widget->GetText());
emit SignalExePath(index, custom_widget->GetText());//}}
双进度条代理:
// 双进度条代理classProgressBarDelegate:publicQStyledItemDelegate{
Q_OBJECT
public:ProgressBarDelegate(QObject* parent =nullptr);~ProgressBarDelegate();protected:virtualvoidpaint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const;};
双进度条代理实现cpp:
#include<QStyleOptionProgressBar>ProgressBarDelegate::ProgressBarDelegate(QObject* parent /*= nullptr*/){}ProgressBarDelegate::~ProgressBarDelegate(){}voidProgressBarDelegate::paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const{if(index.isValid()){
QRect rect = option.rect;int m_x = option.rect.x();int m_y = option.rect.y();// 0是cpu 1是gpu//int flag = index.data(Qt::UserRole + 1).toInt();//if (flag == 0)//{// 图标
QPixmap cpu_pixmap =QPixmap(8,8);
cpu_pixmap.load(QString(":/QtDelegateTest/res/CPU.png"));
painter->drawPixmap(m_x +5, m_y +7, cpu_pixmap);// CPU进度条
QStyleOptionProgressBar cpu_bar;
QRect cpu_bar_rect;
cpu_bar_rect.setRect(rect.left()+30, rect.top(), rect.width()-30, rect.height()/2-2);
cpu_bar.rect = cpu_bar_rect;
cpu_bar.progress = index.data(Qt::UserRole).toInt();
cpu_bar.maximum =100;
cpu_bar.minimum =0;
cpu_bar.textAlignment = Qt::AlignCenter;
cpu_bar.text =QString::number(cpu_bar.progress)+"%";
cpu_bar.textVisible =true;QApplication::style()->drawControl(QStyle::CE_ProgressBar,&cpu_bar, painter);//}//else if (flag == 1)//{
QPixmap mem_pixmap =QPixmap(8,8);
mem_pixmap.load(QString(":/QtDelegateTest/res/内存.png"));
painter->drawPixmap(m_x +5, m_y+option.rect.height()/2+7, mem_pixmap);// 内存进度条
QStyleOptionProgressBar mem_bar;
QRect mem_bar_rect;
mem_bar_rect.setRect(rect.left()+30, rect.top()+ rect.height()/2+2, rect.width()-30, rect.height()/2-4);
mem_bar.progress = index.data(Qt::UserRole+1).toInt();
mem_bar.maximum =100;
mem_bar.minimum =0;
mem_bar.textAlignment = Qt::AlignCenter;
mem_bar.rect = mem_bar_rect;
mem_bar.text =QString::number(mem_bar.progress)+"%";
mem_bar.textVisible =true;QApplication::style()->drawControl(QStyle::CE_ProgressBar,&mem_bar, painter);//}}else{QStyledItemDelegate::paint(painter, option, index);}}
代理实现类汇总CustomDelegate.h
#pragmaonce#include<QObject>#include<QItemDelegate>#include<QLineEdit>#include<QComboBox>#include<QCheckBox>#include<QSpinBox>#include<QDoubleSpinBox>#include<QList>#include<QApplication>#include<QStyledItemDelegate>#include<QHeaderView>#include<QMouseEvent>#include<QPainter>#include<QStandardItemModel>// ComboBox委托classComboBoxDelegate:publicQItemDelegate{
Q_OBJECT
public:ComboBoxDelegate(QObject* parent =0):QItemDelegate(parent){}// 开始编辑状态
QWidget*createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const{
QComboBox* editor =newQComboBox(parent);//if (flag == false)//{// return editor;//}if(m_list.isEmpty())returnNULL;
QStandardItemModel* model =newQStandardItemModel(editor);for(int i =0; i < m_list.count(); i++){
QStandardItem* item =newQStandardItem(m_list.at(i));
item->setTextAlignment(Qt::AlignCenter);
item->setToolTip(ip_list.at(i));
item->setData(ip_list.at(i), Qt::UserRole);
model->setItem(i, item);}
editor->setModel(model);//editor->setCurrentIndex(0);
editor->setCurrentText(index.data(Qt::EditRole).toString());return editor;}// 正在编辑状态voidsetEditorData(QWidget* editor,const QModelIndex& index)const{
QString text = index.model()->data(index, Qt::EditRole).toString();
QComboBox* comboBox =static_cast<QComboBox*>(editor);connect(comboBox,&QComboBox::currentTextChanged,this,[=](const QString& text){// 用于置脏数据来着 可以根据需求灵活修改//emit ComboTextChanged(index, text);});
comboBox->setCurrentText(text);}// 退出编辑状态voidsetModelData(QWidget* editor, QAbstractItemModel* model,const QModelIndex& index)const{//if (flag == false)// return;
QComboBox* comboBox =static_cast<QComboBox*>(editor);
QString text = comboBox->currentText();
QString ip;
QStandardItemModel* comb_model =dynamic_cast<QStandardItemModel*>(comboBox->model());if(comb_model){
QStandardItem* item = comb_model->item(comboBox->currentIndex());
ip = item->data(Qt::UserRole).toString();}if(text != index.data().toString()){//model->blockSignals(true);
model->setData(index, ip, Qt::UserRole);
model->setData(index, text, Qt::EditRole);//model->setData(index, "", Qt::UserRole+1);//model->blockSignals(false);}//emit ComboTextChanged(index, text);//emit sigStudentSeatChange();}voidupdateEditorGeometry(QWidget* editor,const QStyleOptionViewItem& option,const QModelIndex& index)const{
editor->setGeometry(option.rect);}// 参数数量可以根据需求灵活修改voidsetMenuList(QStringList _site_name_list, QStringList _site_ip_list){
m_list = _site_name_list;
ip_list = _site_ip_list;}// void setSignalFlag(bool _flag)// {// flag = _flag;// }
signals:// 可以根据需求添加自定义信号进行处理//void ComboTextChanged(const QModelIndex& index, const QString text)const;//void sigStudentSeatChange(const QTableWidgetItem * _item)const;private:
QStringList m_list;
QStringList ip_list;//bool flag; // true为可编辑状体 false为不可编辑状态};// 状态代理classStatusDelegate:publicQStyledItemDelegate{
Q_OBJECT
public:StatusDelegate(QObject* parent =nullptr){};~StatusDelegate(){}protected:voidpaint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const;booleditorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index);private:
QString m_text;};//只读代理classReadOnlyDelegate:publicQItemDelegate{
Q_OBJECT
public:ReadOnlyDelegate(QObject* parent =0):QItemDelegate(parent){}
QWidget*createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const{returnnullptr;}};//spinBox委托classSpinBoxDelegate:publicQItemDelegate{
Q_OBJECT
public:SpinBoxDelegate(QObject* parent =0):QItemDelegate(parent){ m_minimum =0; m_maxinum =0; m_singleStep =0;}
QWidget*createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const{
QSpinBox* editor =newQSpinBox(parent);
editor->setMinimum(m_minimum);
editor->setMaximum(m_maxinum);
editor->setSingleStep(m_singleStep);return editor;}voidsetEditorData(QWidget* editor,const QModelIndex& index)const{int value = index.model()->data(index, Qt::EditRole).toInt();
QSpinBox* spinbox =static_cast<QSpinBox*>(editor);// 此处注释部分为Qt5实现方法 为了解决函数重载的信号绑定问题 Qt升级后将函数重载的函数更改了名字如下所示connect(spinbox,/*static_cast<void (QSpinBox::*)(const QString&)>*/(&QSpinBox::/*valueChanged*/textChanged),this,[=](const QString& value){
emit SpinBoxValueChanged(index, value);});
spinbox->setValue(value);}voidsetModelData(QWidget* editor, QAbstractItemModel* model,const QModelIndex& index)const{
QSpinBox* spinBox =static_cast<QSpinBox*>(editor);int value = spinBox->value();if(model->data(index, Qt::EditRole).toInt()!= value)
model->setData(index, value, Qt::EditRole);}voidupdateEditorGeometry(QWidget* editor,const QStyleOptionViewItem& option,const QModelIndex& index)const{
editor->setGeometry(option.rect);}voidsetSpinBoxProperty(double minimum,double maxinum,double singleStep){
m_minimum =(int)minimum;
m_maxinum =(int)maxinum;
m_singleStep =(int)singleStep;}
signals:voidSpinBoxValueChanged(const QModelIndex& index,const QString& value)const;private:int m_minimum;// 最小值int m_maxinum;// 最大值int m_singleStep;// 每步调整大小};// DoubleSpinBox委托classDoubleSpinBoxDelegate:publicQItemDelegate{
Q_OBJECT
public:DoubleSpinBoxDelegate(QObject* parent =0):QItemDelegate(parent){ m_minimum =0; m_maxinum =0; m_singleStep =0; m_decimals =0;}
QWidget*createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const{
QDoubleSpinBox* editor =newQDoubleSpinBox(parent);
editor->setMinimum(m_minimum);
editor->setMaximum(m_maxinum);
editor->setSingleStep(m_singleStep);
editor->setDecimals(m_decimals);return editor;}voidsetEditorData(QWidget* editor,const QModelIndex& index)const{double value = index.model()->data(index, Qt::EditRole).toDouble();
QDoubleSpinBox* doubleSpinBox =static_cast<QDoubleSpinBox*>(editor);// 此处注释部分为Qt5实现方法 为了解决函数重载的信号绑定问题 Qt升级后将函数重载的函数更改了名字如下所示connect(doubleSpinBox,/*static_cast<void (QDoubleSpinBox::*)(const QString&)>*/(&QDoubleSpinBox::textChanged/*valueChanged*/),this,[=](const QString& value){
emit DoubleSpinBoxValueChanged(index, value);});
doubleSpinBox->setValue(value);}voidsetModelData(QWidget* editor, QAbstractItemModel* model,const QModelIndex& index)const{
QDoubleSpinBox* doubleSpinBox =static_cast<QDoubleSpinBox*>(editor);double value = doubleSpinBox->value();if(model->data(index, Qt::EditRole).toDouble()!= value)
model->setData(index,QString::number(value,'f', m_decimals), Qt::EditRole);}voidupdateEditorGeometry(QWidget* editor,const QStyleOptionViewItem& option,const QModelIndex& index)const{
editor->setGeometry(option.rect);}voidsetDoubleSpinBoxProperty(double minimum,double maxinum,double singleStep,int decimals){
m_minimum = minimum;
m_maxinum = maxinum;
m_singleStep = singleStep;// 每步调整多少
m_decimals = decimals;// 小数点后几位}
signals:voidDoubleSpinBoxValueChanged(const QModelIndex& index,const QString& value)const;private:double m_minimum;double m_maxinum;double m_singleStep;int m_decimals;};// checkBox勾选框代理classCheckBoxDelegate:publicQStyledItemDelegate{
Q_OBJECT
public:CheckBoxDelegate(QObject* parent =0){}protected:virtual QSize sizeHint(const QStyleOptionViewItem& option,const QModelIndex& index)const;virtualvoidpaint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const;virtualbooleditorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index);
signals:voidCheckStateChanged(const QModelIndex& _index,int _state);};// 表头添加checkBoxclassCCheckBoxHeaderView:publicQHeaderView{
Q_OBJECT
public:CCheckBoxHeaderView(int checkBoxColumnID, Qt::Orientation orientation, QWidget* parent);~CCheckBoxHeaderView(){}voidsetChecked(bool ischeck){
m_checkBoxIsOn = ischeck;updateSection(m_checkBoxColumnId);}voidsetSorted(bool isSort){
m_isSort = isSort;}protected:voidmousePressEvent(QMouseEvent* event);voidpaintSection(QPainter* painter,const QRect& rect,int logicalIndex)const;
signals:voidsig_AllChecked(bool);private:int m_checkBoxColumnId;bool m_checkBoxIsOn;bool m_isSort;};// pushButton代理classPushbuttonDelegate:publicQItemDelegate{
Q_OBJECT
public:PushbuttonDelegate(QObject* parent =0){}~PushbuttonDelegate(){}protected:voidpaint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const;booleditorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index);public:voidsetText(const QString& text);
signals:voidsig_buttonClicked(const QModelIndex& index,const QRect& rect);private:
QMap<QModelIndex, QStyleOptionButton*>m_pBtns;
QString m_text;};// 自定义组件#include<QPushButton>#include<QFileDialog>#include<QHBoxLayout>#include<QObject>classCustomWidget:publicQWidget{
Q_OBJECT
public:explicitCustomWidget(QWidget* parent =0);~CustomWidget();public:voidSetText(QString _text);
QString GetText();private slots:voidSlotButtonclicked();private:
QLineEdit* le_path_;
QPushButton* pb_open_;
QString exe_path_;
QHBoxLayout* main_layout_;};// 自定义组合代理LineEdit+pushButton// 结合上面类进行使用 先创建qwidget再把widget放进代理类classCustomComDelegate:publicQItemDelegate{
Q_OBJECT
public:CustomComDelegate(QObject* parent =nullptr);~CustomComDelegate();
signals:voidSignalExePath(const QModelIndex _index, QString _exe_path)const;protected:virtualvoidpaint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const;virtual QSize sizeHint(const QStyleOptionViewItem& option,const QModelIndex& index)const;virtual QWidget*createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const;virtualvoidsetEditorData(QWidget* editor,const QModelIndex& index)const;virtualvoidsetModelData(QWidget* editor, QAbstractItemModel* model,const QModelIndex& index)const;};// 双进度条代理classProgressBarDelegate:publicQStyledItemDelegate{
Q_OBJECT
public:ProgressBarDelegate(QObject* parent =nullptr);~ProgressBarDelegate();protected:virtualvoidpaint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const;};
代理实现类CustomDelegate.cpp
#include"CustomDelegate.h"voidStatusDelegate::paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const{constbool enabled = option.state & QStyle::State_Enabled;constbool active = option.state & QStyle::State_Active;constbool selected = option.state & QStyle::State_Selected;if(enabled && active && selected)
painter->fillRect(option.rect, option.palette.highlight());if(enabled && selected &&!active){
painter->fillRect(option.rect, option.palette.color(QPalette::Inactive, QPalette::Highlight));}int height = option.rect.height();int width = option.rect.width();int m_x = option.rect.x()+ width /4-5;int m_y = option.rect.y()+ height /2-5;
QString site_status = index.data(Qt::UserRole).toString();
painter->save();//QColor brush = Qt::transparent;if(index.data(Qt::UserRole).toString()=="关于"){//brush = QColor(6, 176, 37);
QPixmap pixmap =QPixmap(8,8);
pixmap.load(QString(":/QtDelegateTest/res/关于.png"));
painter->drawPixmap(m_x -10, m_y, pixmap);
painter->drawText(m_x, option.rect.y(), width *3/4, height, Qt::AlignCenter, site_status);}elseif(index.data(Qt::UserRole).toString()=="设置"){//brush = QColor(177, 177, 177);
QPixmap pixmap =QPixmap(8,8);
pixmap.load(QString(":/QtDelegateTest/res/设置.png"));
painter->drawPixmap(m_x -10, m_y, pixmap);
painter->drawText(m_x, option.rect.y(), width *3/4, height, Qt::AlignCenter, site_status);}elseif(index.data(Qt::UserRole).toString()=="退出"){//brush = QColor(255, 0, 0);
QPixmap pixmap =QPixmap(8,8);
pixmap.load(QString(":/QtDelegateTest/res/退出.png"));
painter->drawPixmap(m_x -10, m_y, pixmap);
painter->drawText(m_x, option.rect.y(), width *3/4, height, Qt::AlignCenter, site_status);}
painter->restore();}boolStatusDelegate::editorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index){returnQStyledItemDelegate::editorEvent(event, model, option, index);}static QRect CheckBoxRect(const QStyleOptionViewItem& viewItemStyleOptions){
QStyleOptionButton checkBoxStyleOption;
QRect checkBoxRect =QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator,&checkBoxStyleOption);
QPoint checkBoxPoint(viewItemStyleOptions.rect.x()+ viewItemStyleOptions.rect.width()/2- checkBoxRect.width()/2,
viewItemStyleOptions.rect.y()+ viewItemStyleOptions.rect.height()/2- checkBoxRect.height()/2);returnQRect(checkBoxPoint, checkBoxRect.size());}
QSize CheckBoxDelegate::sizeHint(const QStyleOptionViewItem& option,const QModelIndex& index)const{
QStyleOptionViewItem opt = option;
QSize opt_size =QStyledItemDelegate::sizeHint(option, index);returnQSize(40,opt_size.height());}voidCheckBoxDelegate::paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const{//const bool enabled = option.state & QStyle::State_Enabled;//const bool active = option.state & QStyle::State_Active;//const bool selected = option.state & QStyle::State_Selected; 绘制原生背景//if (enabled && active && selected)// painter->fillRect(option.rect, option.palette.highlight());//if (enabled && selected && !active)// painter->fillRect(option.rect, option.palette.color(QPalette::Inactive, QPalette::Highlight));
QStyleOptionViewItem opt = option;bool checked = index.model()->data(index, Qt::DisplayRole).toBool();
QStyleOptionButton checkBoxStyleOption;
checkBoxStyleOption.state |= QStyle::State_Enabled;
checkBoxStyleOption.state |= checked ? QStyle::State_On : QStyle::State_Off;
checkBoxStyleOption.rect =CheckBoxRect(opt);
painter->setPen(Qt::black);
QRect text_rect =CheckBoxRect(opt);
text_rect.setWidth(text_rect.width()+20);
painter->drawText(text_rect, Qt::AlignRight | Qt::AlignVCenter,QString::number(index.row()+1));QApplication::style()->drawControl(QStyle::CE_CheckBox,&checkBoxStyleOption, painter);}boolCheckBoxDelegate::editorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index){if((event->type()== QEvent::MouseButtonRelease)||(event->type()== QEvent::MouseButtonDblClick)){
QMouseEvent* mouseEvent =static_cast<QMouseEvent*>(event);if(mouseEvent->button()!= Qt::LeftButton ||!CheckBoxRect(option).contains(mouseEvent->pos())){returntrue;}if(event->type()== QEvent::MouseButtonDblClick)returntrue;}elseif(event->type()== QEvent::KeyPress){if(static_cast<QKeyEvent*>(event)->key()!= Qt::Key_Space &&static_cast<QKeyEvent*>(event)->key()!= Qt::Key_Select)returnfalse;}elsereturnfalse;bool checked = index.model()->data(index, Qt::DisplayRole).toBool();if(checked ==false)
emit CheckStateChanged(index,1);else
emit CheckStateChanged(index,0);return model->setData(index,!checked, Qt::EditRole);}CCheckBoxHeaderView::CCheckBoxHeaderView(int checkBoxColumnId, Qt::Orientation orientation, QWidget* parent):QHeaderView(orientation, parent){
m_checkBoxColumnId = checkBoxColumnId;
m_checkBoxIsOn =false;
m_isSort =false;}voidCCheckBoxHeaderView::paintSection(QPainter* painter,const QRect& rect,int logicalIndex)const{
painter->save();QHeaderView::paintSection(painter, rect, logicalIndex);
painter->restore();if(logicalIndex == m_checkBoxColumnId){
QStyleOptionButton option;int width =3;for(int i =0; i < logicalIndex;++i)
width +=sectionSize(i);
option.rect =QRect(width,5,15,15);if(m_checkBoxIsOn)
option.state = QStyle::State_On;else
option.state = QStyle::State_Off;this->style()->drawControl(QStyle::CE_CheckBox,&option, painter);}}voidCCheckBoxHeaderView::mousePressEvent(QMouseEvent* event){int x = event->pos().x();int y = event->pos().y();if(visualIndexAt(event->pos().x())== m_checkBoxColumnId){//if (event->pos().x() >= 3 && event->pos().x() <= 18 && event->pos().y() >= 5 && event->pos().y() <= 20){this->setSectionsClickable(true);if(m_checkBoxIsOn)
m_checkBoxIsOn =false;else
m_checkBoxIsOn =true;this->updateSection(m_checkBoxColumnId);// 可以连接这个信号将下面所有checkbox状态改变
emit sig_AllChecked(m_checkBoxIsOn);}//else//{// this->setSectionsClickable(m_isSort);//}}else{this->setSectionsClickable(m_isSort);}QHeaderView::mousePressEvent(event);}voidPushbuttonDelegate::setText(const QString& text){
m_text = text;}voidPushbuttonDelegate::paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const{constbool enabled = option.state & QStyle::State_Enabled;constbool active = option.state & QStyle::State_Active;constbool selected = option.state & QStyle::State_Selected;
QStyleOptionButton button;
button.rect = option.rect.adjusted(6,6,-6,-6);
button.text = m_text;
button.state = option.state;
button.iconSize =QSize(18,18);
QPixmap pixmap =QPixmap(8,8);
pixmap.load(QString(":/QtDelegateTest/res/设置.png"));
button.icon =QIcon(pixmap);//! \获取按钮状态bool pressed = index.data(Qt::UserRole +2).toBool();
button.state |= pressed ? QStyle::State_Sunken : QStyle::State_Raised;if(enabled && active && selected)
painter->fillRect(option.rect, option.palette.highlight());if(enabled && selected &&!active){
painter->fillRect(option.rect, option.palette.color(QPalette::Inactive, QPalette::Highlight));}
button.palette.setColor(QPalette::All, QPalette::ButtonText, painter->pen().color());QApplication::style()->drawControl(QStyle::CE_PushButton,&button, painter);}boolPushbuttonDelegate::editorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index){if(event->type()== QEvent::MouseButtonPress || event->type()== QEvent::MouseButtonRelease){if(QMouseEvent* mouseEvent =static_cast<QMouseEvent*>(event)){if(mouseEvent->button()== Qt::LeftButton){bool pressed =false;(event->type()== QEvent::MouseButtonPress)? pressed =true: pressed =false;
model->setData(index, pressed,/*Button_State_Sunken*/Qt::UserRole +2);if(event->type()== QEvent::MouseButtonPress){/* QString base_type = model->data(model->index(index.row(), index.column() - 2)).toString();*/
QStyleOption option_base = option;
QRect rect = option_base.rect;
emit sig_buttonClicked(index, rect);}returntrue;}}}returntrue;}// 自定义组合代理CustomWidget::CustomWidget(QWidget* parent /*= 0*/):QWidget(parent),exe_path_(){
pb_open_ =newQPushButton("...");
pb_open_->setFixedSize(25,25);
le_path_ =newQLineEdit();// 设置不可编辑
le_path_->setEnabled(true);
main_layout_ =newQHBoxLayout();
main_layout_->addWidget(le_path_);
main_layout_->addWidget(pb_open_);
main_layout_->setContentsMargins(0,0,0,0);
main_layout_->setSpacing(0);this->setLayout(main_layout_);connect(pb_open_,&QPushButton::clicked,this,&CustomWidget::SlotButtonclicked);}CustomWidget::~CustomWidget(){}voidCustomWidget::SlotButtonclicked(){
QString exe_path = le_path_->text();if(exe_path.isEmpty()){
exe_path =QFileDialog::getOpenFileName(this,"选择应用程序路径","C:/Users/admin/Desktop/","应用程序(*.exe)");}else{
exe_path =QFileDialog::getOpenFileName(this,"选择应用程序路径", exe_path,"应用程序(*.exe)");}if(!exe_path.isEmpty()){
le_path_->setText(exe_path);}}voidCustomWidget::SetText(QString _text){
le_path_->setText(_text);}
QString CustomWidget::GetText(){return le_path_->text();}// 自定义组合代理CustomComDelegate::CustomComDelegate(QObject* parent /*= nullptr*/):QItemDelegate(parent){}CustomComDelegate::~CustomComDelegate(){}voidCustomComDelegate::paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const{QItemDelegate::paint(painter, option, index);}
QSize CustomComDelegate::sizeHint(const QStyleOptionViewItem& option,const QModelIndex& index)const{returnQItemDelegate::sizeHint(option, index);}
QWidget*CustomComDelegate::createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index)const{
CustomWidget* custom_widget =newCustomWidget(parent);
custom_widget->installEventFilter(const_cast<CustomComDelegate*>(this));return custom_widget;}voidCustomComDelegate::setEditorData(QWidget* editor,const QModelIndex& index)const{
QString value = index.model()->data(index, Qt::DisplayRole).toString();
CustomWidget* custom_widget =qobject_cast<CustomWidget*>(editor);if(!value.isEmpty()){
custom_widget->SetText(value);}else{QItemDelegate::setEditorData(editor, index);}}voidCustomComDelegate::setModelData(QWidget* editor, QAbstractItemModel* model,const QModelIndex& index)const{
CustomWidget* custom_widget =qobject_cast<CustomWidget*>(editor);// if (custom_widget->GetText().isEmpty()){// model->setData(index, "");// }// else{
model->setData(index, custom_widget->GetText());
emit SignalExePath(index, custom_widget->GetText());//}}#include<QStyleOptionProgressBar>ProgressBarDelegate::ProgressBarDelegate(QObject* parent /*= nullptr*/){}ProgressBarDelegate::~ProgressBarDelegate(){}voidProgressBarDelegate::paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index)const{if(index.isValid()){
QRect rect = option.rect;int m_x = option.rect.x();int m_y = option.rect.y();// 0是cpu 1是gpu//int flag = index.data(Qt::UserRole + 1).toInt();//if (flag == 0)//{// 图标
QPixmap cpu_pixmap =QPixmap(8,8);
cpu_pixmap.load(QString(":/QtDelegateTest/res/CPU.png"));
painter->drawPixmap(m_x +5, m_y +7, cpu_pixmap);// CPU进度条
QStyleOptionProgressBar cpu_bar;
QRect cpu_bar_rect;
cpu_bar_rect.setRect(rect.left()+30, rect.top(), rect.width()-30, rect.height()/2-2);
cpu_bar.rect = cpu_bar_rect;
cpu_bar.progress = index.data(Qt::UserRole).toInt();
cpu_bar.maximum =100;
cpu_bar.minimum =0;
cpu_bar.textAlignment = Qt::AlignCenter;
cpu_bar.text =QString::number(cpu_bar.progress)+"%";
cpu_bar.textVisible =true;QApplication::style()->drawControl(QStyle::CE_ProgressBar,&cpu_bar, painter);//}//else if (flag == 1)//{
QPixmap mem_pixmap =QPixmap(8,8);
mem_pixmap.load(QString(":/QtDelegateTest/res/内存.png"));
painter->drawPixmap(m_x +5, m_y+option.rect.height()/2+7, mem_pixmap);// 内存进度条
QStyleOptionProgressBar mem_bar;
QRect mem_bar_rect;
mem_bar_rect.setRect(rect.left()+30, rect.top()+ rect.height()/2+2, rect.width()-30, rect.height()/2-4);
mem_bar.progress = index.data(Qt::UserRole+1).toInt();
mem_bar.maximum =100;
mem_bar.minimum =0;
mem_bar.textAlignment = Qt::AlignCenter;
mem_bar.rect = mem_bar_rect;
mem_bar.text =QString::number(mem_bar.progress)+"%";
mem_bar.textVisible =true;QApplication::style()->drawControl(QStyle::CE_ProgressBar,&mem_bar, painter);//}}else{QStyledItemDelegate::paint(painter, option, index);}}
使用代理类QtDelegateTest.h
#pragmaonce#include<QtWidgets/QMainWindow>#include<QObject>#include"ui_QtDelegateTest.h"#include"CustomDelegate.h"classQtDelegateTest:publicQMainWindow{
Q_OBJECT
public:QtDelegateTest(QWidget *parent = Q_NULLPTR);private:
Ui::QtDelegateTestClass ui;// combobox测试voidComboboxTest();// 状态测试voidStatusTest();// 只读代理测试voidReadOnlyTest();// spinBox委托voidSpinBoxDelegateTest();// DoubleSpinBox委托voidDoubleBoxDelegateTest();// checkBox勾选框代理voidCheckBoxDelegateTest();// 表头添加checkBoxvoidCCheckBoxHeaderViewTest();// 设置所有checkbox状态voidSlotAllCheckboxStatus(bool _flag);// pushButton代理voidPushbuttonDelegateTest();// 自定义组件voidCustomWidgetTest();// 存放exe路径voidSlotSetExePath(const QModelIndex _index, QString _exe_path);// 双进度条测试voidProgressBarDelegateTest();
ComboBoxDelegate* combobox_delegate;// combobox测试
SpinBoxDelegate* spin_box_delegate;// spinBox委托
DoubleSpinBoxDelegate* double_spin_box;// DoubleSpinBox委托
CCheckBoxHeaderView* ccheck_box_header;// 表头添加checkBox};
使用代理类QtDelegateTest.cpp
#include"QtDelegateTest.h"QtDelegateTest::QtDelegateTest(QWidget* parent):QMainWindow(parent){
ui.setupUi(this);ComboboxTest();StatusTest();ReadOnlyTest();SpinBoxDelegateTest();DoubleBoxDelegateTest();CheckBoxDelegateTest();CCheckBoxHeaderViewTest();PushbuttonDelegateTest();CustomWidgetTest();ProgressBarDelegateTest();}voidQtDelegateTest::ComboboxTest(){
combobox_delegate =new ComboBoxDelegate;
ui.delegate_tableWidget->setItemDelegateForColumn(0, combobox_delegate);
QStringList name;
name.append("1");
name.append("2");
QStringList data;
data.append("一");
data.append("二");
combobox_delegate->setMenuList(name, data);}voidQtDelegateTest::StatusTest(){
ui.delegate_tableWidget->setItemDelegateForColumn(1,new StatusDelegate);
QTableWidgetItem* item = ui.delegate_tableWidget->item(0,1);
item->setData(Qt::UserRole,"关于");// 设置只读的一种方式
item->setFlags(Qt::ItemIsEnabled);
item = ui.delegate_tableWidget->item(1,1);
item->setData(Qt::UserRole,"设置");
item->setFlags(Qt::ItemIsEnabled);
item = ui.delegate_tableWidget->item(2,1);
item->setData(Qt::UserRole,"退出");
item->setFlags(Qt::ItemIsEnabled);}voidQtDelegateTest::ReadOnlyTest(){
ui.delegate_tableWidget->setItemDelegateForColumn(2,new ReadOnlyDelegate);}voidQtDelegateTest::SpinBoxDelegateTest(){
spin_box_delegate =new SpinBoxDelegate;
spin_box_delegate->setSpinBoxProperty(0,1000,2);
ui.delegate_tableWidget->setItemDelegateForColumn(3, spin_box_delegate);}voidQtDelegateTest::DoubleBoxDelegateTest(){
double_spin_box =new DoubleSpinBoxDelegate;
double_spin_box->setDoubleSpinBoxProperty(0,1000,0.01,5);
ui.delegate_tableWidget->setItemDelegateForColumn(4, double_spin_box);}voidQtDelegateTest::CheckBoxDelegateTest(){
ui.delegate_tableWidget->setItemDelegateForColumn(5,new CheckBoxDelegate);}voidQtDelegateTest::CCheckBoxHeaderViewTest(){
ccheck_box_header =newCCheckBoxHeaderView(5, Qt::Horizontal, ui.delegate_tableWidget);
ui.delegate_tableWidget->setHorizontalHeader(ccheck_box_header);connect(ccheck_box_header,&CCheckBoxHeaderView::sig_AllChecked,this,&QtDelegateTest::SlotAllCheckboxStatus);}voidQtDelegateTest::SlotAllCheckboxStatus(bool _flag){int rowCount = ui.delegate_tableWidget->rowCount();for(int i =0; i < rowCount;++i){
QTableWidgetItem* item = ui.delegate_tableWidget->item(i,5);
item->setData(Qt::DisplayRole, _flag);}}voidQtDelegateTest::PushbuttonDelegateTest(){
PushbuttonDelegate* pushbutton_delegate =new PushbuttonDelegate;
pushbutton_delegate->setText("设置");
ui.delegate_tableWidget->setItemDelegateForColumn(6, pushbutton_delegate);}voidQtDelegateTest::CustomWidgetTest(){
CustomComDelegate* custom =new CustomComDelegate;
ui.delegate_tableWidget->setItemDelegateForColumn(7, custom);connect(custom,&CustomComDelegate::SignalExePath,this,&QtDelegateTest::SlotSetExePath);}voidQtDelegateTest::SlotSetExePath(const QModelIndex _index, QString _exe_path){
QFileInfo info(_exe_path);
QString name = info.fileName();
QString exe_name = name.replace(".exe","");
ui.delegate_tableWidget->item(_index.row(), _index.column()-1)->setData(Qt::DisplayRole, exe_name);}voidQtDelegateTest::ProgressBarDelegateTest(){
ui.delegate_tableWidget->setItemDelegateForColumn(8,new ProgressBarDelegate);
ui.delegate_tableWidget->item(0,8)->setData(Qt::UserRole,80);
ui.delegate_tableWidget->item(0,8)->setData(Qt::UserRole+1,70);
ui.delegate_tableWidget->item(1,8)->setData(Qt::UserRole ,70);
ui.delegate_tableWidget->item(1,8)->setData(Qt::UserRole +1,60);
ui.delegate_tableWidget->item(2,8)->setData(Qt::UserRole,70);
ui.delegate_tableWidget->item(2,8)->setData(Qt::UserRole +1,60);}
版权归原作者 奇树谦 所有, 如有侵权,请联系我们删除。