0


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

参考:
QTableView表格控件代理详解
https://blog.csdn.net/u010031316/article/details/120366295
示例程序运行环境:WIN10,VS2022,QT6.3
创建的QtWidgetApplication项目,解决方案目录及main主函数如下图:
VS
qrc资源文件中就放了几个从阿里巴巴矢量图库下载的几张图:
qrc

ui中就部署了一个qtablewidget,如图所示:
ui部署图
分模块代码
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);}
标签: qt ui 开发语言

本文转载自: https://blog.csdn.net/weixin_42964413/article/details/125112366
版权归原作者 奇树谦 所有, 如有侵权,请联系我们删除。

“Qt|表格代理的实现及使用代码qtableview和qtablewidget均适用”的评论:

还没有评论