自定义代理类
- 一.应用场景
- 二.创建自定义代理类
- 1.创建一个类
- 2.共有继承父类
- 3.添加宏
- 4.初始化父类
- 5.拿到我们需要重写的虚函数
- 三.实现父类的4个虚函数
- 1.创建代理组件
- 2.设置代理组件数据
- 3.设置模型数据
- 4.跟新代理组件的位置
- 四.使用代理类
- 1.头文件
- 2.私有成员
- 3.视图设置代理
- 五.其他列添加代理
- 1.绩效
- ①.创建代理
- ②设置代理数据
- ③设置模型数据
- ④跟新代理位置
- ⑤使用代理
- 2.性别和岗位
- ①.创建代理
- ②设置代理数据
- ③设置模型数据
- ④跟新代理位置
- ⑤使用代理
- 3.生日
- ①.创建代理
- ②设置代理数据
- ③设置模型数据
- ④跟新代理位置
- ⑤使用代理
- 六.总结
一.应用场景
当我们希望在视图中添加一些组件时,可以使用到自定义代理。
我们可以在上个案例的基础上来进行修改,需要蔬菜的可以dd我,这里使用了另外一个txt文件
,使用我们上次的源代码需要改。
文本文件的表头是7列,所以我们改成7。
插入和添加行的信息也需要修改。
OK,准备工作就做好了。
二.创建自定义代理类
1.创建一个类
取个名就行了。
2.共有继承父类
在刚刚创建的类的头文件中
记得加头文件
#ifndef QSALAYDELEGATE_H
#define QSALAYDELEGATE_H#include <QStyledItemDelegate>//用来自定义代理的父类头文件class QSalayDelegate:public QStyledItemDelegate
{
public:QSalayDelegate();
};
3.添加宏
class QSalayDelegate:public QStyledItemDelegate
{Q_OBJECT
public:QSalayDelegate();
};
4.初始化父类
class QSalayDelegate:public QStyledItemDelegate
{Q_OBJECT
public:QSalayDelegate(QObject*perant=0);
};
在cpp文件中:
QSalayDelegate::QSalayDelegate(QObject*perant):QStyledItemDelegate(perant)
{}
5.拿到我们需要重写的虚函数
进入到父类中
将这4个虚函数拿到刚刚创建头文件中!
头文件中
#ifndef QSALAYDELEGATE_H
#define QSALAYDELEGATE_H#include <QStyledItemDelegate>class QSalayDelegate:public QStyledItemDelegate
{Q_OBJECT
public:QSalayDelegate(QObject*perant=0);QWidget *createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index) const override;void setEditorData(QWidget *editor, const QModelIndex &index) const override;void setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const override;void updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index) const override;
};#endif // QSALAYDELEGATE_H
代理类的准备工作就做好了,接下来就是重点了!
三.实现父类的4个虚函数
1.创建代理组件
可以直接在cpp中生成定义
我们这里是想对薪资来添加一个自定义代理组件,所以我们可以使用SpinBox组件
QWidget *QSalayDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{QSpinBox *editor=new QSpinBox(parent);//创建一个代理组件//可以对组件设置一些属性editor->setMinimum(2000);//最小薪资editor->setMaximum(100000);//最大薪资editor->setSingleStep(100);//每次可以加一百return editor;
}
2.设置代理组件数据
我们要想要设置代理组件的数据,我们可以通过拿到模型的数据来设置
void QSalayDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{QSpinBox *spinBox=static_cast<QSpinBox *>(editor);//因为参数editor的类型是祖宗所以我们要强制类型转换int value=index.model()->data(index).toUInt();//通过模型索引拿到模型数据spinBox->setValue(value);//设置代理组件数据
}
看注释哈,我写的这么详细!
3.设置模型数据
我们要想设置模型数据,我们可以先拿到代理的数据来设置
void QSalayDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{QSpinBox *spinBox=static_cast<QSpinBox *>(editor);//相当于拿到代理组件spinBox->interpretText();//解析数据,这里相当于转换成整数int value=spinBox->value();//拿到代理的数据model->setData(index,value);//设置模型数据
}
4.跟新代理组件的位置
void QSalayDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{editor->setGeometry(option.rect);//默认的位置就是在单元格的矩形位置
}
四.使用代理类
1.头文件
在mainwindow.h中
#include "qsalaydelegate.h"
2.私有成员
3.视图设置代理
在mainwindow.cpp的构造函数中
//指定代理,通过列来指定,4列就是薪资ui->tableView->setItemDelegateForColumn(4,&salayDelegate);
运行结果:
这样我们的代理就添加好了!
五.其他列添加代理
1.绩效
准备工作都一样。
①.创建代理
QWidget *QFloatDelegate::createEditor (QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index)const
{QDoubleSpinBox *editor=new QDoubleSpinBox(parent);editor->setMinimum(0);editor->setMaximum(5);editor->setSingleStep(0.1);editor->setDecimals(1);//设置小数点精度return editor;
}
②设置代理数据
void QFloatDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{QDoubleSpinBox *spinBox=static_cast<QDoubleSpinBox *>(editor);float value=index.model()->data(index).toFloat();spinBox->setValue(value);
}
③设置模型数据
void QFloatDelegate::setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const
{QDoubleSpinBox *spinBox=static_cast<QDoubleSpinBox *>(editor);float value=spinBox->value();QString str=QString::asprintf("%.1f",value);model->setData(index,value);
}
④跟新代理位置
void QFloatDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index) const
{editor->setGeometry(option.rect);
}
⑤使用代理
ui->tableView->setItemDelegateForColumn(5,&floatDelegate);
运行结果:
2.性别和岗位
①.创建代理
QWidget *ComboBoxDelegate::createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index) const
{QComboBox *editor=new QComboBox(parent);editor->addItem("软件工程师");editor->addItem("高级程序员");return editor;
}
如果我这样写会产生一个问题,那就是只能代理一列,我想要的效果是职业和性别都可以下拉框选择,所有这里我们不能写死了,可以通过成员数据来动态的传值!
可以在类中加入:
并且实现:
void ComboBoxDelegate::setList(QStringList list)
{this->list=list;
}
QWidget *ComboBoxDelegate::createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index) const
{QComboBox *editor=new QComboBox(parent);editor->addItems(this->list);return editor;
}
②设置代理数据
void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{QComboBox* comboBox=static_cast<QComboBox*>(editor);comboBox->setCurrentText(index.model()->data(index).toString());
}
③设置模型数据
void ComboBoxDelegate::setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const
{QComboBox* comboBox=static_cast<QComboBox*>(editor);model->setData(index,comboBox->currentText());
}
④跟新代理位置
void ComboBoxDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index) const
{editor->setGeometry(option.rect);
}
⑤使用代理
mainwindow.h中要有头文件和添加数据成员
comBoxGender.setList(QStringList{"男","女"});ui->tableView->setItemDelegateForColumn(1,&comBoxGender);comBoxJobs.setList(QStringList{"软件工程师","项目经理","高级程序员","助理"});ui->tableView->setItemDelegateForColumn(2,&comBoxJobs);
运行结果:
这个例子就讲了一个代理用在多列!
3.生日
①.创建代理
QWidget *QDateDelegate::createEditor(QWidget *parent,const QStyleOptionViewItem &option,const QModelIndex &index) const
{QDateEdit*editor=new QDateEdit(parent);editor->setMinimumDate(QDate(1900,1,1));editor->setMaximumDate(QDate(2020,1,1));editor->setCalendarPopup(true);//设置弹出 日历return editor;
}
②设置代理数据
void QDateDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{QDateEdit *dateEdit=static_cast<QDateEdit *>(editor);QString str=index.model()->data(index).toString();QDate date=QDate::fromString(str,"yyyy-MM-dd");dateEdit->setDate(date);
}
③设置模型数据
void QDateDelegate::setModelData(QWidget *editor,QAbstractItemModel *model,const QModelIndex &index) const
{QDateEdit *dateEdit=static_cast<QDateEdit *>(editor);QDate date=dateEdit->date();model->setData(index,date.toString("yyyy-MM-dd"));
}
④跟新代理位置
void QDateDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index) const
{QRect rect=option.rect;rect.setWidth(rect.width()*1.5);//将日历代理组件的宽度设为原来的1.5倍editor->setGeometry(rect);
}
⑤使用代理
ui->tableView->setItemDelegateForColumn(2,&dateDelegate);
运行结果:
OK,完结了!
六.总结
主要是知道代理的应用场景,和模板化套路。
优秀的公司赚取利润,伟大的公司赢得人心。