【qt】自定义代理类

简介: 【qt】自定义代理类

一.应用场景

当我们希望在视图中添加一些组件时,可以使用到自定义代理。

我们可以在上个案例的基础上来进行修改,需要蔬菜的可以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,完结了!

六.总结

主要是知道代理的应用场景,和模板化套路。


优秀的公司赚取利润,伟大的公司赢得人心。

相关文章
|
12天前
|
C++
Qt中的信号与槽如何学习?(包括自定义信号)这篇文章告诉你
以现实中的事件来举例的话,例如有两把不同颜色的信号枪,分别是红色,绿色,打响不通颜色的信号枪会触发不同的槽发生,比如说打响红色这个人就跑步,绿色就走步,但是还有一个很重要的机制,那就是连接,我们需要把信号枪去跟这个人的动作连接起来。 如果上面理解没问题的话我们可以把信号和槽看成两个工具,我们最重要的是如何去把这两个工具连接起来。 它的作用可以让我们更加灵活的去使用不同窗口间的切换以及某些事件的连接。
|
2月前
|
监控 数据可视化 Linux
Qt Model&View&Delegate(模型-视图-代理) 介绍和使用
Qt Model&View&Delegate(模型-视图-代理) 介绍和使用
Qt Model&View&Delegate(模型-视图-代理) 介绍和使用
|
2月前
|
开发者
Qt 布局(QSplitter 类&QDockWidget 类) 总结
Qt 布局(QSplitter 类&QDockWidget 类) 总结
Qt 布局(QSplitter 类&QDockWidget 类) 总结
|
21天前
使用QMovie类来实现在QT中的动态加载效果。
使用QMovie类来实现在QT中的动态加载效果。
21 0
|
1月前
|
XML JSON 前端开发
Qt委托代理机制之《Model/View/Delegate使用方法》
Qt委托代理机制之《Model/View/Delegate使用方法》
37 1
|
2月前
|
Windows
Qt 目录操作(QDir 类)及展示系统文件实战 & QFilelnfo 类介绍和获取文件属性项目实战
Qt 目录操作(QDir 类)及展示系统文件实战 & QFilelnfo 类介绍和获取文件属性项目实战
Qt 目录操作(QDir 类)及展示系统文件实战 & QFilelnfo 类介绍和获取文件属性项目实战
|
1月前
|
API
【Qt】Qt定时器类QTimer
【Qt】Qt定时器类QTimer
|
2月前
|
搜索推荐
【qt】自定义界面类
【qt】自定义界面类
20 0
|
11天前
|
数据安全/隐私保护 C++ 计算机视觉
Qt(C++)开发一款图片防盗用水印制作小工具
文本水印是一种常用的防盗用手段,可以将文本信息嵌入到图片、视频等文件中,用于识别和证明文件的版权归属。在数字化和网络化的时代,大量的原创作品容易被不法分子盗用或侵犯版权,因此加入文本水印成为了保护原创作品和维护知识产权的必要手段。 通常情况下,文本水印可以包含版权声明、制作者姓名、日期、网址等信息,以帮助识别文件的来源和版权归属。同时,为了增强防盗用效果,文本水印通常会采用字体、颜色、角度等多种组合方式,使得水印难以被删除或篡改,有效地降低了盗用意愿和风险。 开发人员可以使用图像处理技术和编程语言实现文本水印的功能,例如使用Qt的QPainter类进行文本绘制操作,将文本信息嵌入到图片中,
31 1
Qt(C++)开发一款图片防盗用水印制作小工具