Qt MVC之自定义代理

文章介绍了在Qt的MVC架构中,自定义代理用于控制Model在View中的显示方式和用户交互。通过继承QAbstractItemDelegate或QItemDelegate,实现特定的虚函数,如sizeHint、paint、createEditor等,可以创建自定义代理以满足特殊需求。文章提供了QSpinBox代理的案例,展示如何在item编辑时使用QSpinBox进行数值输入。
摘要由CSDN通过智能技术生成

1、自定义代理的介绍

在Qt的MVC(Model-View-Controller)架构中,代理(Delegate)扮演着很重要的角色代理用于控制Model在View中的显示方式,并负责处理用户与View的交互事件。在一些特殊的情况下,Qt提供了一些内置代理(例如QStyledItemDelegate、QItemDelegate等)用于控制View的显示方式。但是有时候,我们需要更加灵活地控制View的显示方式,这时就需要自定义代理。

自定义代理需要继承QAbstractItemDelegate类或则QItemDelegate类,并实现其中的一些虚函数,例如:

//返回项的大小,用于设置View中项的大小
QSize sizeHint(const QStyleOptionViewItem &option,
                   const QModelIndex &index) const override;
//在View中绘制项,可以通过调用painter对象的方法绘制出所需的效果
void paint(QPainter *painter,
               const QStyleOptionViewItem &option,
               const QModelIndex &index) const override;
//创建编辑器,用于在View中对项进行编辑
QWidget *createEditor(QWidget *parent,
                          const QStyleOptionViewItem &option,
                          const QModelIndex &index) const override;
//将Model中的数据设置到编辑器中,以便进行编辑
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
//将编辑器中的数据保存到Model中
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
//更新编辑器的位置和大小
void updateEditorGeometry(QWidget *editor,
                              const QStyleOptionViewItem &option,
                              const QModelIndex &index) const override;

除此之外,还可以重写其他的虚函数以实现更加自定义化的效果。
自定义代理的使用方法如下:

  • 创建自定义代理对象。
  • 将代理对象设置到View中的项上,可以使用View的setItemDelegate()函数。
  • 在Model中存储数据,并通知View进行更新。

通过自定义代理,我们可以灵活地控制View中项的显示方式,并实现一些特殊的交互效果

2、自定义代理的案例

当我们想重新实现一个代理时,可以让子类继承QItemDelegate。实现item编辑时特定的效果,比如在item编辑时我们设置一个QSpinBox返回。

SpinBoxDelegate.h如下:

#pragma once

#include <QItemDelegate>
#include<QSpinBox>
#pragma execution_character_set("utf-8")

class SpinBoxDelegate  : public QItemDelegate
{
	Q_OBJECT

public:
	SpinBoxDelegate(QObject *parent);
protected:
	virtual QWidget* createEditor(QWidget* parent,const QStyleOptionViewItem& option,const QModelIndex& index) const override;
	virtual void setEditorData(QWidget* editor, const QModelIndex& index) const override;
	virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override;
	virtual void updateEditorGeometry(QWidget* editor,const QStyleOptionViewItem& option,const QModelIndex& index) const override;
	~SpinBoxDelegate();
};

SpinBoxDelegate.cpp如下:

#include "SpinBoxDelegate.h"

SpinBoxDelegate::SpinBoxDelegate(QObject *parent)
	: QItemDelegate(parent)
{}

QWidget* SpinBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
	auto* spinbox = new QSpinBox(parent);
	spinbox->setMinimum(0);
	spinbox->setMaximum(100);
	return spinbox;
}

void SpinBoxDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const
{
	int value = index.model()->data(index, Qt::EditRole).toInt();
	auto* spinBox = static_cast<QSpinBox*>(editor);
	spinBox->setValue(value);
}

void SpinBoxDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const
{
	auto* spinBox = static_cast<QSpinBox*>(editor);
	//更新spinBox中的值,方便显示
	spinBox->interpretText();
	int value = spinBox->value();
	model->setData(index, value, Qt::EditRole);
}

void SpinBoxDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
	editor->setGeometry(option.rect);
}

SpinBoxDelegate::~SpinBoxDelegate()
{}

在MainWindow中创建一个表格视图(QTableView),然后使用QStandardItemModel这个模型,通过for循环向模型中传入数据,然后在视图中设置该模型,最后创建上面的代理,通过setItemDelegage()这个接口,设置代理。

测试代码的效果如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值