参考:
QTableView表格控件代理详解
https://blog.csdn.net/u010031316/article/details/120366295
运行环境:WIN10,VS2022,QT6.3
创建的QtWidgetApplication项目,解决方案目录及main主函数如下图:

qrc资源文件中就放了几个从阿里巴巴矢量图库下载的几张图:

ui中就部署了一个qtablewidget,如图所示:

分模块代码
ComboBox委托:

// ComboBox委托
class ComboBoxDelegate :public QItemDelegate
{Q_OBJECTpublic:ComboBoxDelegate(QObject* parent = 0) :QItemDelegate(parent){}// 开始编辑状态QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index)const{QComboBox* editor = new QComboBox(parent);//if (flag == false)//{//    return editor;//}if (m_list.isEmpty())return NULL;QStandardItemModel* model = new QStandardItemModel(editor);for (int i = 0; i < m_list.count(); i++){QStandardItem* item = new QStandardItem(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;}// 正在编辑状态void setEditorData(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);}// 退出编辑状态void setModelData(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();}void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)const{editor->setGeometry(option.rect);}// 参数数量可以根据需求灵活修改void setMenuList(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为不可编辑状态
};

状态代理:

// 状态代理
class StatusDelegate : public QStyledItemDelegate
{Q_OBJECT
public:StatusDelegate(QObject* parent = nullptr) {};~StatusDelegate() {}
protected:void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
private:QString m_text;
};

状态代理实现cpp:

void StatusDelegate::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));}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);}else if (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);}else if (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();
}bool StatusDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
{return QStyledItemDelegate::editorEvent(event, model, option, index);
}

只读代理:

//只读代理
class ReadOnlyDelegate: public QItemDelegate
{Q_OBJECT
public:ReadOnlyDelegate(QObject* parent = 0) :QItemDelegate(parent) {}QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index)const{return nullptr;}
};

spinBox委托:

//spinBox委托
class SpinBoxDelegate: public QItemDelegate
{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 = new QSpinBox(parent);editor->setMinimum(m_minimum);editor->setMaximum(m_maxinum);editor->setSingleStep(m_singleStep);return editor;}void setEditorData(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);}void setModelData(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);}void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)const{editor->setGeometry(option.rect);}void setSpinBoxProperty(double minimum, double maxinum, double singleStep){m_minimum = (int)minimum;m_maxinum = (int)maxinum;m_singleStep = (int)singleStep;}signals:void SpinBoxValueChanged(const QModelIndex& index, const QString& value)const;private:int m_minimum;     // 最小值int m_maxinum;        // 最大值int m_singleStep; // 每步调整大小
};

DoubleSpinBox委托:

// DoubleSpinBox委托
class DoubleSpinBoxDelegate: public QItemDelegate
{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 = new QDoubleSpinBox(parent);editor->setMinimum(m_minimum);editor->setMaximum(m_maxinum);editor->setSingleStep(m_singleStep);editor->setDecimals(m_decimals);return editor;}void setEditorData(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);}void setModelData(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);}void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)const{editor->setGeometry(option.rect);}void setDoubleSpinBoxProperty(double minimum, double maxinum, double singleStep, int decimals){m_minimum = minimum;m_maxinum = maxinum;m_singleStep = singleStep;   // 每步调整多少m_decimals = decimals;    // 小数点后几位}signals:void DoubleSpinBoxValueChanged(const QModelIndex& index, const QString& value)const;private:double m_minimum;double m_maxinum;double m_singleStep;int m_decimals;
};

checkBox勾选框代理:

// checkBox勾选框代理
class CheckBoxDelegate :public QStyledItemDelegate
{Q_OBJECT
public:CheckBoxDelegate(QObject* parent = 0) {}
protected:virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const;virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);signals:void CheckStateChanged(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);return QRect(checkBoxPoint, checkBoxRect.size());
}QSize CheckBoxDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{QStyleOptionViewItem opt = option;QSize opt_size = QStyledItemDelegate::sizeHint(option, index);return QSize(40,opt_size.height());
}void CheckBoxDelegate::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);
}bool CheckBoxDelegate::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())){return true;}if (event->type() == QEvent::MouseButtonDblClick)return true;}else if (event->type() == QEvent::KeyPress){if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)return false;}elsereturn false;bool checked = index.model()->data(index, Qt::DisplayRole).toBool();if (checked == false)emit CheckStateChanged(index, 1);elseemit CheckStateChanged(index, 0);return model->setData(index, !checked, Qt::EditRole);
}

表头添加checkBox:

//   表头添加checkBox
class CCheckBoxHeaderView : public QHeaderView
{Q_OBJECT
public:CCheckBoxHeaderView(int checkBoxColumnID, Qt::Orientation orientation, QWidget* parent);~CCheckBoxHeaderView() {}void setChecked(bool ischeck){m_checkBoxIsOn = ischeck;updateSection(m_checkBoxColumnId);}void setSorted(bool isSort){m_isSort = isSort;}protected:void mousePressEvent(QMouseEvent* event);void paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const;signals:void sig_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;
}void CCheckBoxHeaderView::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;elseoption.state = QStyle::State_Off;this->style()->drawControl(QStyle::CE_CheckBox, &option, painter);}
}void CCheckBoxHeaderView::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;elsem_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代理
class PushbuttonDelegate : public QItemDelegate
{Q_OBJECT
public:PushbuttonDelegate(QObject* parent = 0) {}~PushbuttonDelegate() {}protected:void paint(QPainter* painter, const QStyleOptionViewItem& option,const QModelIndex& index) const;bool editorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option, const QModelIndex& index);
public:void setText(const QString& text);signals:void sig_buttonClicked(const QModelIndex& index, const QRect& rect);private:QMap<QModelIndex, QStyleOptionButton*>m_pBtns;QString m_text;
};

pushButton代理实现cpp:

void PushbuttonDelegate::setText(const QString& text)
{m_text = text;
}void PushbuttonDelegate::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;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);
}bool PushbuttonDelegate::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);}return true;}}}return true;
}

自定义组件:

// 自定义组件
#include <QPushButton>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QObject>
class  CustomWidget:public QWidget
{Q_OBJECT
public:explicit CustomWidget(QWidget* parent = 0);~CustomWidget();
public:void SetText(QString _text);QString GetText();
private slots:void SlotButtonclicked();
private:QLineEdit* le_path_;QPushButton* pb_open_;QString exe_path_;QHBoxLayout* main_layout_;
};// 自定义组合代理LineEdit+pushButton
// 结合上面类进行使用 先创建qwidget再把widget放进代理类
class CustomComDelegate: public QItemDelegate
{Q_OBJECT
public:CustomComDelegate(QObject* parent = nullptr);~CustomComDelegate();signals:void SignalExePath(const QModelIndex _index, QString _exe_path) const;protected:virtual void paint(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;virtual void setEditorData(QWidget* editor, const QModelIndex& index) const;virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;};

自定义组件实现cpp:

// 自定义组合代理
CustomWidget::CustomWidget(QWidget* parent /*= 0*/):QWidget(parent), exe_path_()
{pb_open_ = new QPushButton("...");pb_open_->setFixedSize(25, 25);le_path_ = new QLineEdit();// 设置不可编辑le_path_->setEnabled(true);main_layout_ = new QHBoxLayout();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()
{}void CustomWidget::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);}
}void CustomWidget::SetText(QString _text)
{le_path_->setText(_text);
}QString CustomWidget::GetText()
{return le_path_->text();
}// 自定义组合代理
CustomComDelegate::CustomComDelegate(QObject* parent /*= nullptr*/):QItemDelegate(parent)
{}CustomComDelegate::~CustomComDelegate()
{}void CustomComDelegate::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
{return QItemDelegate::sizeHint(option, index);
}QWidget* CustomComDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{CustomWidget* custom_widget = new CustomWidget(parent);custom_widget->installEventFilter(const_cast<CustomComDelegate*>(this));return custom_widget;
}void CustomComDelegate::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);}
}void CustomComDelegate::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());//}
}

双进度条代理:

// 双进度条代理
class ProgressBarDelegate:public QStyledItemDelegate
{Q_OBJECT
public:ProgressBarDelegate(QObject* parent = nullptr);~ProgressBarDelegate();protected:virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;};

双进度条代理实现cpp:

#include <QStyleOptionProgressBar>ProgressBarDelegate::ProgressBarDelegate(QObject* parent /*= nullptr*/)
{}ProgressBarDelegate::~ProgressBarDelegate()
{}void ProgressBarDelegate::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

#pragma once#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委托
class ComboBoxDelegate :public QItemDelegate
{Q_OBJECTpublic:ComboBoxDelegate(QObject* parent = 0) :QItemDelegate(parent){}// 开始编辑状态QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index)const{QComboBox* editor = new QComboBox(parent);//if (flag == false)//{//    return editor;//}if (m_list.isEmpty())return NULL;QStandardItemModel* model = new QStandardItemModel(editor);for (int i = 0; i < m_list.count(); i++){QStandardItem* item = new QStandardItem(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;}// 正在编辑状态void setEditorData(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);}// 退出编辑状态void setModelData(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();}void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)const{editor->setGeometry(option.rect);}// 参数数量可以根据需求灵活修改void setMenuList(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为不可编辑状态
};// 状态代理
class StatusDelegate : public QStyledItemDelegate
{Q_OBJECT
public:StatusDelegate(QObject* parent = nullptr) {};~StatusDelegate() {}
protected:void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
private:QString m_text;
};//只读代理
class ReadOnlyDelegate: public QItemDelegate
{Q_OBJECT
public:ReadOnlyDelegate(QObject* parent = 0) :QItemDelegate(parent) {}QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index)const{return nullptr;}
};//spinBox委托
class SpinBoxDelegate: public QItemDelegate
{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 = new QSpinBox(parent);editor->setMinimum(m_minimum);editor->setMaximum(m_maxinum);editor->setSingleStep(m_singleStep);return editor;}void setEditorData(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);}void setModelData(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);}void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)const{editor->setGeometry(option.rect);}void setSpinBoxProperty(double minimum, double maxinum, double singleStep){m_minimum = (int)minimum;m_maxinum = (int)maxinum;m_singleStep = (int)singleStep;}signals:void SpinBoxValueChanged(const QModelIndex& index, const QString& value)const;private:int m_minimum;     // 最小值int m_maxinum;        // 最大值int m_singleStep; // 每步调整大小
};// DoubleSpinBox委托
class DoubleSpinBoxDelegate: public QItemDelegate
{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 = new QDoubleSpinBox(parent);editor->setMinimum(m_minimum);editor->setMaximum(m_maxinum);editor->setSingleStep(m_singleStep);editor->setDecimals(m_decimals);return editor;}void setEditorData(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);}void setModelData(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);}void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)const{editor->setGeometry(option.rect);}void setDoubleSpinBoxProperty(double minimum, double maxinum, double singleStep, int decimals){m_minimum = minimum;m_maxinum = maxinum;m_singleStep = singleStep;   // 每步调整多少m_decimals = decimals;    // 小数点后几位}signals:void DoubleSpinBoxValueChanged(const QModelIndex& index, const QString& value)const;private:double m_minimum;double m_maxinum;double m_singleStep;int m_decimals;
};// checkBox勾选框代理
class CheckBoxDelegate :public QStyledItemDelegate
{Q_OBJECT
public:CheckBoxDelegate(QObject* parent = 0) {}
protected:virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const;virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);signals:void CheckStateChanged(const QModelIndex& _index, int _state);
};//    表头添加checkBox
class CCheckBoxHeaderView : public QHeaderView
{Q_OBJECT
public:CCheckBoxHeaderView(int checkBoxColumnID, Qt::Orientation orientation, QWidget* parent);~CCheckBoxHeaderView() {}void setChecked(bool ischeck){m_checkBoxIsOn = ischeck;updateSection(m_checkBoxColumnId);}void setSorted(bool isSort){m_isSort = isSort;}protected:void mousePressEvent(QMouseEvent* event);void paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const;signals:void sig_AllChecked(bool);private:int m_checkBoxColumnId;bool m_checkBoxIsOn;bool m_isSort;
};//    pushButton代理
class PushbuttonDelegate : public QItemDelegate
{Q_OBJECT
public:PushbuttonDelegate(QObject* parent = 0) {}~PushbuttonDelegate() {}protected:void paint(QPainter* painter, const QStyleOptionViewItem& option,const QModelIndex& index) const;bool editorEvent(QEvent* event, QAbstractItemModel* model,const QStyleOptionViewItem& option, const QModelIndex& index);
public:void setText(const QString& text);signals:void sig_buttonClicked(const QModelIndex& index, const QRect& rect);private:QMap<QModelIndex, QStyleOptionButton*>m_pBtns;QString m_text;
};// 自定义组件
#include <QPushButton>
#include <QFileDialog>
#include <QHBoxLayout>
#include <QObject>
class  CustomWidget:public QWidget
{Q_OBJECT
public:explicit CustomWidget(QWidget* parent = 0);~CustomWidget();
public:void SetText(QString _text);QString GetText();
private slots:void SlotButtonclicked();
private:QLineEdit* le_path_;QPushButton* pb_open_;QString exe_path_;QHBoxLayout* main_layout_;
};// 自定义组合代理LineEdit+pushButton
// 结合上面类进行使用 先创建qwidget再把widget放进代理类
class CustomComDelegate: public QItemDelegate
{Q_OBJECT
public:CustomComDelegate(QObject* parent = nullptr);~CustomComDelegate();signals:void SignalExePath(const QModelIndex _index, QString _exe_path) const;protected:virtual void paint(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;virtual void setEditorData(QWidget* editor, const QModelIndex& index) const;virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const;};// 双进度条代理
class ProgressBarDelegate:public QStyledItemDelegate
{Q_OBJECT
public:ProgressBarDelegate(QObject* parent = nullptr);~ProgressBarDelegate();protected:virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;};

代理实现类CustomDelegate.cpp

#include "CustomDelegate.h"void StatusDelegate::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));}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);}else if (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);}else if (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();
}bool StatusDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
{return QStyledItemDelegate::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);return QRect(checkBoxPoint, checkBoxRect.size());
}QSize CheckBoxDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{QStyleOptionViewItem opt = option;QSize opt_size = QStyledItemDelegate::sizeHint(option, index);return QSize(40,opt_size.height());
}void CheckBoxDelegate::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);
}bool CheckBoxDelegate::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())){return true;}if (event->type() == QEvent::MouseButtonDblClick)return true;}else if (event->type() == QEvent::KeyPress){if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space && static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select)return false;}elsereturn false;bool checked = index.model()->data(index, Qt::DisplayRole).toBool();if (checked == false)emit CheckStateChanged(index, 1);elseemit 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;
}void CCheckBoxHeaderView::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;elseoption.state = QStyle::State_Off;this->style()->drawControl(QStyle::CE_CheckBox, &option, painter);}
}void CCheckBoxHeaderView::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;elsem_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);
}void PushbuttonDelegate::setText(const QString& text)
{m_text = text;
}void PushbuttonDelegate::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;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);
}bool PushbuttonDelegate::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);}return true;}}}return true;
}// 自定义组合代理
CustomWidget::CustomWidget(QWidget* parent /*= 0*/):QWidget(parent), exe_path_()
{pb_open_ = new QPushButton("...");pb_open_->setFixedSize(25, 25);le_path_ = new QLineEdit();// 设置不可编辑le_path_->setEnabled(true);main_layout_ = new QHBoxLayout();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()
{}void CustomWidget::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);}
}void CustomWidget::SetText(QString _text)
{le_path_->setText(_text);
}QString CustomWidget::GetText()
{return le_path_->text();
}// 自定义组合代理
CustomComDelegate::CustomComDelegate(QObject* parent /*= nullptr*/):QItemDelegate(parent)
{}CustomComDelegate::~CustomComDelegate()
{}void CustomComDelegate::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
{return QItemDelegate::sizeHint(option, index);
}QWidget* CustomComDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{CustomWidget* custom_widget = new CustomWidget(parent);custom_widget->installEventFilter(const_cast<CustomComDelegate*>(this));return custom_widget;
}void CustomComDelegate::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);}
}void CustomComDelegate::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()
{}void ProgressBarDelegate::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

#pragma once#include <QtWidgets/QMainWindow>
#include <QObject>
#include "ui_QtDelegateTest.h"
#include "CustomDelegate.h"class QtDelegateTest : public QMainWindow
{Q_OBJECTpublic:QtDelegateTest(QWidget *parent = Q_NULLPTR);private:Ui::QtDelegateTestClass ui;// combobox测试void ComboboxTest();// 状态测试void StatusTest();// 只读代理测试void ReadOnlyTest();// spinBox委托void SpinBoxDelegateTest();// DoubleSpinBox委托void DoubleBoxDelegateTest();// checkBox勾选框代理void CheckBoxDelegateTest();// 表头添加checkBoxvoid CCheckBoxHeaderViewTest();// 设置所有checkbox状态void SlotAllCheckboxStatus(bool _flag);// pushButton代理void PushbuttonDelegateTest();// 自定义组件void CustomWidgetTest();// 存放exe路径void SlotSetExePath(const QModelIndex _index, QString _exe_path);// 双进度条测试void ProgressBarDelegateTest();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();
}void QtDelegateTest::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);
}void QtDelegateTest::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);
}void QtDelegateTest::ReadOnlyTest()
{ui.delegate_tableWidget->setItemDelegateForColumn(2, new ReadOnlyDelegate);
}void QtDelegateTest::SpinBoxDelegateTest()
{spin_box_delegate = new SpinBoxDelegate;spin_box_delegate->setSpinBoxProperty(0,1000,2);ui.delegate_tableWidget->setItemDelegateForColumn(3, spin_box_delegate);
}void QtDelegateTest::DoubleBoxDelegateTest()
{double_spin_box = new DoubleSpinBoxDelegate;double_spin_box->setDoubleSpinBoxProperty(0, 1000, 0.01, 5);ui.delegate_tableWidget->setItemDelegateForColumn(4, double_spin_box);
}void QtDelegateTest::CheckBoxDelegateTest()
{ui.delegate_tableWidget->setItemDelegateForColumn(5, new CheckBoxDelegate);
}void QtDelegateTest::CCheckBoxHeaderViewTest()
{ccheck_box_header = new CCheckBoxHeaderView(5, Qt::Horizontal, ui.delegate_tableWidget);ui.delegate_tableWidget->setHorizontalHeader(ccheck_box_header);connect(ccheck_box_header, &CCheckBoxHeaderView::sig_AllChecked, this, &QtDelegateTest::SlotAllCheckboxStatus);
}void QtDelegateTest::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);}
}void QtDelegateTest::PushbuttonDelegateTest()
{PushbuttonDelegate* pushbutton_delegate = new PushbuttonDelegate;pushbutton_delegate->setText("设置");ui.delegate_tableWidget->setItemDelegateForColumn(6, pushbutton_delegate);}void QtDelegateTest::CustomWidgetTest()
{CustomComDelegate* custom = new CustomComDelegate;ui.delegate_tableWidget->setItemDelegateForColumn(7, custom);connect(custom, &CustomComDelegate::SignalExePath, this, &QtDelegateTest::SlotSetExePath);
}void QtDelegateTest::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);
}void QtDelegateTest::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);
}

Qt|表格代理的实现及使用代码qtableview和qtablewidget均适用相关推荐

  1. Qt GUI图形图像开发之QT表格控件QTableView详细使用方法与实例

    QT表格控件QTableView简介 ​ 表格视图控件QTableView,需要和QStandardItemModel, 配套使用,这套框架是基于MVC设计模式设计的,M(Model)是QStanda ...

  2. qtabwidget设置表头_Qt GUI图形图像开发之QT表格控件QTableView,QTableWidget复杂表头(多行表头) 及冻结、固定特定的行的详细方法与实例...

    我们在开发过程中对于表格使用频率还是挺高的,使用QT框架开发时候我们使用QTableView或者QTableWidget创建表格. 其中表格分为 表格头与表格体: 对于简单地表格,我们可以设置表头来满 ...

  3. tablewidget 多行表头_Qt GUI图形图像开发之QT表格控件QTableView,QTableWidget复杂表头(多行表头) 及冻结、固定特定的行的详细方法与实例...

    我们在开发过程中对于表格使用频率还是挺高的,使用QT框架开发时候我们使用QTableView或者QTableWidget创建表格. 其中表格分为 表格头与表格体: 对于简单地表格,我们可以设置表头来满 ...

  4. 使用样式表自定义QT表格交替背景色

    关键字: Qt交替背景色; Qt样式表;alternate;alternate-background-color 默认情况下,QTableView.QTableWidget以及QListView都可以 ...

  5. Python 处理表格进行成绩排序的操作代码

    这篇文章主要介绍了Python 处理表格进行成绩排序,也就是说将学生从按照学号排序变为按照成绩从高到低进行排序,具体实现代码跟随小编一起看看吧 一.需求分析 我们首先有一个成绩表单,但是学生的成绩是按 ...

  6. python按某列拆分excel表格_Python对Excel按列值筛选并拆分表格到多个文件的代码...

    场景:集团中心下发本省数据时,并未按地市.业务拆分,现需要按地市.业务拆分并分发到地市. 本文利用Python的pandas包实现了以上场景. 注:本示例代码只实现按单列拆分,如果需要多列筛选拆分,请 ...

  7. elementui表格宽度适应内容_解决elementui表格操作列自适应列宽代码示例

    本篇文章小编给大家分享一下解决elementui表格操作列自适应列宽代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 写死宽度时是这样的: 开始 ...

  8. Qt 通过条件编译区分Debug和Release代码

    Qt 通过条件编译区分Debug和Release代码 ​ 在公司写Bug,发现程序运行全屏不适合调试,通过条件编译搞一下. 文章目录 Qt 通过条件编译区分Debug和Release代码 测试代码 关 ...

  9. Qt 表格导出数据为 excel html csv

    Qt 表格导出数据为 excel html csv 示例 使用WPS导出出错问题 参考: 从QTableView中导出数据到excel(一) qt QTableWidget&&QTab ...

  10. php优秀表格样式,用html和css代码实现各种表格样式的总结

    在我们日常开发工作中,基本上都会有表格的设置,我们都知道表格是展示数据的重要形式,也是网页中非常重要的元素之一,他可以使数据以表格的形式展现在网页中,今天我们就给大家总结一下表格样式! html实现表 ...

最新文章

  1. WEB 打印的相关技术分析
  2. AndroidStudio基础视频教程-整理
  3. 构造函数、原型、继承原来这么简单?来吧,深入浅出
  4. 【itext学习之路】--4.给pdf增加文本水印和图片水印
  5. eplan怎样创建和修改图框_EPLAN标题页及图框的设计
  6. 大学计算机基础上机实践报告,大学计算机基础上机实践报告书册.doc
  7. “十亿赌约”,雷军输,董明珠胜?
  8. 【C/C++】与const有关的指针类型赋值
  9. edit box小技巧
  10. 幽冥岛争霸 - 和女儿一起开发的游戏-单机版基本完成
  11. 【GNN】一份简短入门《图神经网络GNN》笔记小册
  12. JAVA反射性能约慢三个量级
  13. 万由nas系统安装MySQL_ESXi安装万由OS(U-NAS 3.0.9)
  14. 春晚红包:史上最难开卷考试,快手交卷了
  15. Thinkpad T400 Fan error报错非风扇问题解决一例
  16. word 多级编号列表
  17. MATLAB之GIF动图的绘制
  18. 计算机集成制造ppt英语,计算机集成制造cims
  19. 数据库基础、使用C语言构建一个数据库、SQL语言、MySQL
  20. python 基础 Number String List Tuple Diction nary

热门文章

  1. 分布式系统与海量数据处理
  2. Flutter应用程序版本更新与自动升级配置方法
  3. 使用python破解zip、rar压缩包密码
  4. 记录一次成功的EC、BIOS降级操作
  5. 计算机软件答辩ppt范文,计算机毕业答辩ppt模板范文.ppt
  6. 手把手带你SQLite3快速入门
  7. GLSL-Compute Shader
  8. 仿迅雷播放器教程 -- 提取exe资源
  9. 网络安全设备-认识运维安全管理与审计系统(堡垒机)
  10. python从入门到精通资源库_[百度网盘]PYTHON从入门到精通全套资料 - 磁力点点