Qt|表格代理的实现及使用代码qtableview和qtablewidget均适用
参考:
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均适用相关推荐
- Qt GUI图形图像开发之QT表格控件QTableView详细使用方法与实例
QT表格控件QTableView简介 表格视图控件QTableView,需要和QStandardItemModel, 配套使用,这套框架是基于MVC设计模式设计的,M(Model)是QStanda ...
- qtabwidget设置表头_Qt GUI图形图像开发之QT表格控件QTableView,QTableWidget复杂表头(多行表头) 及冻结、固定特定的行的详细方法与实例...
我们在开发过程中对于表格使用频率还是挺高的,使用QT框架开发时候我们使用QTableView或者QTableWidget创建表格. 其中表格分为 表格头与表格体: 对于简单地表格,我们可以设置表头来满 ...
- tablewidget 多行表头_Qt GUI图形图像开发之QT表格控件QTableView,QTableWidget复杂表头(多行表头) 及冻结、固定特定的行的详细方法与实例...
我们在开发过程中对于表格使用频率还是挺高的,使用QT框架开发时候我们使用QTableView或者QTableWidget创建表格. 其中表格分为 表格头与表格体: 对于简单地表格,我们可以设置表头来满 ...
- 使用样式表自定义QT表格交替背景色
关键字: Qt交替背景色; Qt样式表;alternate;alternate-background-color 默认情况下,QTableView.QTableWidget以及QListView都可以 ...
- Python 处理表格进行成绩排序的操作代码
这篇文章主要介绍了Python 处理表格进行成绩排序,也就是说将学生从按照学号排序变为按照成绩从高到低进行排序,具体实现代码跟随小编一起看看吧 一.需求分析 我们首先有一个成绩表单,但是学生的成绩是按 ...
- python按某列拆分excel表格_Python对Excel按列值筛选并拆分表格到多个文件的代码...
场景:集团中心下发本省数据时,并未按地市.业务拆分,现需要按地市.业务拆分并分发到地市. 本文利用Python的pandas包实现了以上场景. 注:本示例代码只实现按单列拆分,如果需要多列筛选拆分,请 ...
- elementui表格宽度适应内容_解决elementui表格操作列自适应列宽代码示例
本篇文章小编给大家分享一下解决elementui表格操作列自适应列宽代码示例,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看. 写死宽度时是这样的: 开始 ...
- Qt 通过条件编译区分Debug和Release代码
Qt 通过条件编译区分Debug和Release代码 在公司写Bug,发现程序运行全屏不适合调试,通过条件编译搞一下. 文章目录 Qt 通过条件编译区分Debug和Release代码 测试代码 关 ...
- Qt 表格导出数据为 excel html csv
Qt 表格导出数据为 excel html csv 示例 使用WPS导出出错问题 参考: 从QTableView中导出数据到excel(一) qt QTableWidget&&QTab ...
- php优秀表格样式,用html和css代码实现各种表格样式的总结
在我们日常开发工作中,基本上都会有表格的设置,我们都知道表格是展示数据的重要形式,也是网页中非常重要的元素之一,他可以使数据以表格的形式展现在网页中,今天我们就给大家总结一下表格样式! html实现表 ...
最新文章
- WEB 打印的相关技术分析
- AndroidStudio基础视频教程-整理
- 构造函数、原型、继承原来这么简单?来吧,深入浅出
- 【itext学习之路】--4.给pdf增加文本水印和图片水印
- eplan怎样创建和修改图框_EPLAN标题页及图框的设计
- 大学计算机基础上机实践报告,大学计算机基础上机实践报告书册.doc
- “十亿赌约”,雷军输,董明珠胜?
- 【C/C++】与const有关的指针类型赋值
- edit box小技巧
- 幽冥岛争霸 - 和女儿一起开发的游戏-单机版基本完成
- 【GNN】一份简短入门《图神经网络GNN》笔记小册
- JAVA反射性能约慢三个量级
- 万由nas系统安装MySQL_ESXi安装万由OS(U-NAS 3.0.9)
- 春晚红包:史上最难开卷考试,快手交卷了
- Thinkpad T400 Fan error报错非风扇问题解决一例
- word 多级编号列表
- MATLAB之GIF动图的绘制
- 计算机集成制造ppt英语,计算机集成制造cims
- 数据库基础、使用C语言构建一个数据库、SQL语言、MySQL
- python 基础 Number String List Tuple Diction nary