#include "delegate.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include Delegate::Delegate(QObject *parent): QStyledItemDelegate(parent) { this->init(); } QWidget *Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/*option*/, const QModelIndex &/*index*/) const { if(delegateType == "QCheckBox") return 0; /*创建编辑器*/ QWidget *editor = new QWidget(parent); /*判断具体的委托,并将编辑器进行响应的设置*/ if(delegateType == "QSpinBox") { //必须加上parent,负责QSpinBox显示在视图外面 QSpinBox *sbox = new QSpinBox(parent); sbox->setRange(sboxMinValue,sboxMaxValue); sbox->setSuffix(sboxSuffixStr); sbox->setPrefix(sboxPrefixStr); sbox->setSingleStep(sboxSingleStep); sbox->setStepType(sboxStepType); sbox->setValue(sboxInitValue); editor = sbox; connect(sbox,SIGNAL(valueChanged(int)),this,SLOT(on_valueChanged(int))); } else if(delegateType == "QDoubleSpinBox") { QDoubleSpinBox *sdbox = new QDoubleSpinBox(parent); sdbox->setRange(0,100); // sdbox->setSuffix(sboxSuffixStr); // sdbox->setPrefix(sboxPrefixStr); sdbox->setSingleStep(0.1); // sdbox->setStepType(sboxStepType); // sdbox->setValue(sboxInitValue); editor = sdbox; connect(sdbox,SIGNAL(valueChanged(double)),this,SLOT(on_valueChanged(double))); } else if(delegateType == "QComboBox") { QComboBox *cbox = new QComboBox(parent); cbox->addItems(cboxItems); cbox->setEditable(cboxEditable); editor = cbox; } else if (delegateType == "QDateTimeEdit") { QDateTimeEdit *dateTime = new QDateTimeEdit(parent); dateTime->setCalendarPopup(true); dateTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); dateTime->calendarWidget()->setLocale(QLocale::Chinese); editor = dateTime; } else if (delegateType == "QDateEdit") { QDateEdit *date = new QDateEdit(parent); date->setCalendarPopup(true); date->setDisplayFormat("yyyy-MM-dd"); date->calendarWidget()->setLocale(QLocale::Chinese); editor = date; } else if (delegateType == "QTimeEdit") { QTimeEdit *time = new QTimeEdit(parent); time->setDisplayFormat("HH:mm:ss"); editor = time; } else if (delegateType == "QLineEdit") { QLineEdit *lineEidt = new QLineEdit(parent); // lineEidt->setReadOnly(true); editor = lineEidt; connect(lineEidt, SIGNAL(textChanged(QString)), this, SLOT(on_valueChanged(QString))); } else if (delegateType == "QLabel") { QLabel *label = new QLabel(parent); editor = label; connect(label, SIGNAL(textChanged(QString)), this, SLOT(on_valueChanged(QString))); } return editor; } void Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const { auto value = index.model()->data(index, Qt::EditRole); if(delegateType == "QSpinBox") { QSpinBox *spinBox = static_cast(editor); spinBox->setValue(value.toInt()); } else if(delegateType == "QDoubleSpinBox") { QDoubleSpinBox *dspinBox = static_cast(editor); dspinBox->setValue(value.toFloat()); } else if(delegateType == "QComboBox") { QComboBox *cbox = static_cast(editor); cbox->setCurrentText(value.toString()); } else if (delegateType == "QDateTimeEdit") { QDateTimeEdit *dateTime = static_cast(editor); dateTime->setDateTime(QDateTime::fromString(value.toString(), "yyyy-MM-dd HH:mm:ss")); } else if (delegateType == "QDateEdit") { QDateEdit *date = static_cast(editor); date->setDate(QDate::fromString(value.toString(), "yyyy-MM-dd")); } else if (delegateType == "QTimeEdit") { QTimeEdit *time = static_cast(editor); time->setTime(QTime::fromString(value.toString(), "HH:mm:ss")); } else if (delegateType == "QLineEdit") { QLineEdit *lineEidt = static_cast(editor); lineEidt->setText(value.toString()); } else if (delegateType == "QLabel") { QLabel *label = static_cast(editor); label->setText(value.toString()); } else { QStyledItemDelegate::setEditorData(editor, index); } } void Delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QVariant value = model->data(index); if(delegateType == "QSpinBox") { QSpinBox *spinBox = static_cast(editor); value = spinBox->value(); } if(delegateType == "QDoubleSpinBox") { QDoubleSpinBox *dspinBox = static_cast(editor); value = dspinBox->value(); } else if(delegateType == "QComboBox") { QComboBox *cbox = static_cast(editor); value = cbox->currentText(); } else if (delegateType == "QDateTimeEdit") { QDateTimeEdit *dateTime = static_cast(editor); value = dateTime->dateTime().toString("yyyy-MM-dd HH:mm:ss"); } else if (delegateType == "QDateEdit") { QDateEdit *date = static_cast(editor); value = date->date().toString("yyyy-MM-dd"); } else if (delegateType == "QTimeEdit") { QTimeEdit *time = static_cast(editor); value = time->time().toString("HH:mm:ss"); } else if (delegateType == "QLineEdit") { QLineEdit *lineEidt = static_cast(editor); value = lineEidt->text(); } else if (delegateType == "QLabel") { QLabel *label = static_cast(editor); value = label->text(); } model->setData(index, value, Qt::EditRole); } void Delegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const { editor->setGeometry(option.rect); } void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { if(index.column() == delegateColumnID) { if(delegateType == "QProgressBar") { drawProgressBar(painter,option,index); } else if(delegateType == "QCheckBox") { drawCheckBox(painter,option,index); } else if(delegateType == "QPushButton") { drawPushButton(painter,option,index); } else if(delegateType == "QPixmap" && judgmentColumn>=0) { drawPixmap(painter,option,index); } else if (delegateType == "QLineEdit" && delegatePwd) { drawLineEdit(painter, option, index); } }//if else { QStyledItemDelegate::paint(painter,option,index); } } bool Delegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) { //Qt6中如果调用了 qApp->setStyleSheet 设置了全局样式的话,鼠标移动也会触发 editorEvent TNND if (event->type() == QEvent::MouseMove) { return false; } //处理编辑数据 QString data = index.data(Qt::DisplayRole).toString(); if (delegateType == "QCheckBox") { //鼠标松开不用处理,不然会重复设置 if (event->type() == QEvent::MouseButtonRelease) { return false; } //如果当前的文字和设置的选中文字一致则说明是选中 checkedText = (data == checkBoxChecked ? checkBoxUnchecked : checkBoxChecked); model->setData(index, checkedText, Qt::EditRole); emit valueChanged(checkedText); } else if (delegateType == "QPushButton") { QMouseEvent *mouseEvent = static_cast(event); mousePoint = mouseEvent->pos(); mousePressed = false; //没有按钮对应的值则不处理 QStringList list = data.split("|"); int count = list.count(); if (data.isEmpty() || count == 0) { return false; } //根据按钮数量自动计算按钮对应的区域 int x = option.rect.x(); int y = option.rect.y(); int width = option.rect.width() / count; int height = option.rect.height(); QList btnRect; for (int i = 0; i < count; ++i) { btnRect << QRect(x + i * width, y, width, height); } if (event->type() == QEvent::MouseButtonPress) { //鼠标按下更新对应按钮区域是否按下,并判断按下的区域是哪个按钮,发送对应的按钮索引和index for (int i = 0; i < count; ++i) { if (btnRect.at(i).contains(mousePoint)) { mousePressed = true; emit buttonClicked(i, index); break; } } } //需要返回真表示需要继续绘制 return true; } //和事件过滤器类似,也需要继续返回执行 return QStyledItemDelegate::editorEvent(event, model, option, index); } void Delegate::init() { delegateType = "QSpinBox"; delegateColumnID = -1; sboxMaxValue = 100; sboxMinValue = 0; sboxPrefixStr = ""; sboxSuffixStr = ""; sboxSingleStep = 1; sboxInitValue = 0; sboxStepType = QAbstractSpinBox::DefaultStepType; cboxItems.clear(); cboxEditable = true; checkBoxChecked = "true"; checkBoxUnchecked = "false"; pgbarMax = 100; pgbarMin = 0; pgbarAlignment = Qt::AlignCenter; isTextVisible = true; invertedAppearance = false; imgOk = QPixmap(":/corr.png"); imgNo = QPixmap(":/erro.png"); imgWidth = 20; imgHeigth = 20; judgmentColumn = -1; judgmentValue = "错误"; judgmentCondition = "contains"; } void Delegate::checkData(const QString &data,bool *selse)const { if (judgmentCondition == "==") { if (data == judgmentValue) { *selse = true; } } else if (judgmentCondition == ">") { if (data.toDouble() > judgmentValue.toDouble()) { *selse = true; } } else if (judgmentCondition == ">=") { if (data.toDouble() >= judgmentValue.toDouble()) { *selse = true; } } else if (judgmentCondition == "<") { if (data.toDouble() < judgmentValue.toDouble()) { *selse = true; } } else if (judgmentCondition == "<=") { if (data.toDouble() <= judgmentValue.toDouble()) { *selse = true; } } else if (judgmentCondition == "!=") { if (data != judgmentValue) { *selse = true; } } else if (judgmentCondition == "contains") { QStringList list = judgmentValue.split("|"); foreach (QString value, list) { if (data.contains(value)) { *selse = true; break; } } } } void Delegate::drawProgressBar(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index)const { //获得视图中的值 int value = index.model()->data(index,Qt::DisplayRole).toInt(); //创建包含QProgressBar样式信息类 QStyleOptionProgressBar soPgbar; //使用我们创建的pgBar初始化soPgbar soPgbar.initFrom(pgBar); //设置最大值和最小值 soPgbar.maximum = pgbarMax; soPgbar.minimum = pgbarMin; //设置进度条值 soPgbar.progress = value; //设置状态 soPgbar.state |= QStyle::State_Enabled; soPgbar.state |= QStyle::State_Horizontal; //设置位置和大小 soPgbar.rect = option.rect; //设置文本 soPgbar.text = QString("%1%").arg(value); //设置文本是否可见 soPgbar.textVisible = isTextVisible; //设置文本居中 soPgbar.textAlignment = pgbarAlignment; //设置进度条的进度方向 soPgbar.invertedAppearance = invertedAppearance; //绘制 QApplication::style()->drawControl(QStyle::CE_ProgressBar,&soPgbar,painter,pgBar); } void Delegate::drawCheckBox(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { //处理复选框委托,判断是否选中,设置选中状态 QString data = index.data(Qt::EditRole).toString(); bool checked = (data == checkBoxChecked); QStyleOptionButton styleOption; styleOption.initFrom(checkBox); styleOption.state = checked ? QStyle::State_On : QStyle::State_Off; styleOption.state |= QStyle::State_Enabled; //设置居中正方形区域 int width = option.rect.width(); int height = option.rect.height(); int size = qMin(width, height); int x = option.rect.center().x() - (size / 4); int y = option.rect.y(); styleOption.rect = QRect(x, y, size, size); QApplication::style()->drawControl(QStyle::CE_CheckBox, &styleOption, painter, checkBox); } void Delegate::drawPushButton(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { //没有按钮对应的值则不处理 QString data = index.data(Qt::DisplayRole).toString(); QStringList list = data.split("|"); int count = list.count(); if (data.isEmpty() || count == 0) { return; } //处理按钮集合委托,自动计算分配宽度 int x = option.rect.x(); int y = option.rect.y(); int width = option.rect.width() / count; int height = option.rect.height(); //分别绘制按钮集合 for (int i = 0; i < count; ++i) { QStyleOptionButton styleOption; styleOption.initFrom(button); styleOption.rect = QRect(x + i * width, y, width, height); styleOption.text = list.at(i); styleOption.state |= QStyle::State_Enabled; //鼠标按下更新对应的样式 if (mousePressed) { if (styleOption.rect.contains(mousePoint)) { styleOption.state |= QStyle::State_Sunken; } } //第四个参数也可以为空,为空的话就不能应用样式表 QApplication::style()->drawControl(QStyle::CE_PushButton, &styleOption, painter, button); } } void Delegate::drawPixmap(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QString data = index.model()->index(index.row(),judgmentColumn).data().toString(); bool selse; checkData(data,&selse); //图标自动缩放到指定大小 QPixmap pixmap = (selse?imgOk:imgNo); pixmap = pixmap.scaled(QSize(imgWidth, imgHeigth), Qt::KeepAspectRatio, Qt::SmoothTransformation); QApplication::style()->drawItemPixmap(painter, option.rect, Qt::AlignCenter, pixmap); } void Delegate::drawLineEdit(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { //统计数量,转换成对应数量的密码样式 QString value = index.model()->data(index, Qt::DisplayRole).toString(); int len = value.length(); QString text; for (int i = 0; i < len; ++i) { text += "●"; } QRect rect = option.rect; rect.setX(rect.x() + 2); painter->drawText(rect, Qt::AlignCenter, text); } void Delegate::on_valueChanged(int value) { emit valueChanged(QString("%1").arg(value)); } void Delegate::on_valueChanged(double value) { emit valueChanged(QString("%1").arg(value)); } void Delegate::on_valueChanged(QString value) { emit valueChanged(QString("%1").arg(value)); } void Delegate::setDelegateType(const QString &delegateType) { this->delegateType = delegateType; /*将需要使用paint绘制的控件在这里new出来。 *为什么不在paint函数中new呢? * 因为不能在const成员函数paint中分配非静态数据成员 */ if(delegateType == "QProgressBar") { pgBar = new QProgressBar; } else if(delegateType == "QPushButton") { button = new QPushButton; } else if (delegateType == "QCheckBox") { checkBox = new QCheckBox; } } void Delegate::setDelegateColumn(const int delegateColumnID) { this->delegateColumnID = delegateColumnID; } void Delegate::setSboxMaxValue(const int max) { sboxMaxValue = max; } void Delegate::setSboxMinValue(const int min) { sboxMinValue = min; } void Delegate::setSboxPrefixStr(const QString &prefix) { sboxPrefixStr = prefix; } void Delegate::setSboxSuffixStr(const QString &suffix) { sboxSuffixStr = suffix; } void Delegate::setSboxSingleStep(const int SingleStep) { sboxSingleStep = SingleStep; } void Delegate::setSboxInitValue(const int initValue) { sboxInitValue = initValue; } void Delegate::setSboxStepType(QAbstractSpinBox::StepType st) { sboxStepType = st; } void Delegate::setCboxItems(const QStringList &items) { cboxItems = items; } void Delegate::setCboxEditable(bool editable) { cboxEditable = editable; } void Delegate::setPgBarRange(const int min, const int max) { pgbarMin = min; pgbarMax = max; } void Delegate::setPgBarTextVisible(bool isTextVisible) { this->isTextVisible = isTextVisible; } void Delegate::setPgBarAlignment(Qt::Alignment pgbarAlignment) { this->pgbarAlignment = pgbarAlignment; } void Delegate::setInvertedAppearance(bool invertedAppearance) { this->invertedAppearance = invertedAppearance; } void Delegate::setCheckBoxText(const QString &checkBoxChecked, const QString &checkBoxUnchecked) { this->checkBoxChecked = checkBoxChecked; this->checkBoxUnchecked = checkBoxUnchecked; } void Delegate::setImgOk(const QPixmap &imgOk) { this->imgOk = imgOk; } void Delegate::setImgNo(const QPixmap &imgNo) { this->imgNo = imgNo; } void Delegate::setImgSize(int width,int heigth) { this->imgWidth = width; this->imgHeigth = heigth; } void Delegate::setJudgmentColumn(int column) { this->judgmentColumn = column; } void Delegate::setJudgmentValue(const QString &value) { this->judgmentValue = value; } void Delegate::setJudgmentCondition(const QString &condition) { this->judgmentCondition = condition; } void Delegate::setDelegatePwd(bool showDelegatePwd) { this->delegatePwd = showDelegatePwd; } void Delegate::setComboBox(QAbstractItemView *view, QAbstractItemModel *model) { for (int row = 0; row < model->rowCount(); ++row) { QComboBox *comboBox = new QComboBox(); comboBox->addItems(cboxItems); view->setIndexWidget(model->index(row, delegateColumnID), comboBox); } }