【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,完结了!

六.总结

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


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

相关文章
|
4月前
Qt类结构分析
Qt类结构分析
69 3
|
2月前
(8)Qt中的自定义信号
本文介绍了如何在Qt框架中创建和使用自定义信号,并通过一个父子窗口切换的示例来展示自定义信号的实现和应用。
104 3
(8)Qt中的自定义信号
|
2月前
(7)Qt中的自定义槽(函数)
这篇文章介绍了在Qt中如何定义和使用自定义槽函数,包括类成员函数、静态类成员函数、全局函数和lambda表达式作为槽函数的示例,以及使用lambda表达式时的注意事项。
67 2
(7)Qt中的自定义槽(函数)
|
3月前
|
设计模式 前端开发 安全
Qt注册类对象单例与单类型区别
在进行开发时,应当根据具体的应用场景和需求来选择使用单例模式或是单类型。如果是全局服务或状态管理,可能需要单例模式;如果是为了使QML环境下的不同组件能够访问到同一个后端服务对象,则可能需要使用单类型。
49 2
|
4月前
|
搜索推荐 C++
【Qt 学习笔记】Qt窗口 | 对话框 | 创建自定义对话框
【Qt 学习笔记】Qt窗口 | 对话框 | 创建自定义对话框
148 4
|
4月前
|
编解码 开发框架
【Qt 学习笔记】Qt窗口 | Qt窗口介绍 | QMainwindow类及各组件介绍
【Qt 学习笔记】Qt窗口 | Qt窗口介绍 | QMainwindow类及各组件介绍
328 3
|
4月前
|
容器
【Qt 学习笔记】Qt常用控件 | 容器类控件 | Group Box的使用及说明
【Qt 学习笔记】Qt常用控件 | 容器类控件 | Group Box的使用及说明
333 3
|
4月前
|
容器
【Qt 学习笔记】Qt常用控件 | 容器类控件 | Tab Widget的使用及说明
【Qt 学习笔记】Qt常用控件 | 容器类控件 | Tab Widget的使用及说明
212 2
|
4月前
【Qt 学习笔记】Qt常用控件 | 输入类控件 | Slider的使用及说明
【Qt 学习笔记】Qt常用控件 | 输入类控件 | Slider的使用及说明
486 2
|
4月前
【Qt 学习笔记】Qt常用控件 | 输入类控件 | Dial的使用及说明
【Qt 学习笔记】Qt常用控件 | 输入类控件 | Dial的使用及说明
204 2