自定义委托

自定义委托

​ 代理就是在视图组件上为编辑数据提供的临时编辑器,例如在 QTableView 组件上编辑一个单元格的数据时,默认会提供一个 QLineEdit 编辑框。代理负责从模型获取相应的数据,然后将其显示在编辑器里,修改数据后又将编辑器里的数据保存到模型中 。

​ 以下是对QPushButtonQComboxBoxQLineEditQCheckBox的示例。

QWControlDelegate.h

#pragma once

#include <QStyledItemDelegate>
#include <QItemDelegate>
#include <QObject>
#include <QPushButton>
#include <QCheckBox>
#include <QLineEdit>
#include <QSpinBox>
#include <QComboBox>
#include <QMessageBox>
#include <QMouseEvent>
#include <QApplication>
#include <QPainter>
#include <QStyleOption>
#include <QDesktopWidget>
#include <QToolTip>
#include <QDebug>
#include <QMessageBox>
#include <QListWidget>
#include <QTableWidget>

/*QWPushButtonDelegate*/
class QWPushButtonDelegate : public QStyledItemDelegate
{
public:
	Q_OBJECT

public:
	void setItems(QStringList items);//初始化设置列表内容
	void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const override;
	bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);

signals:
	void edit1st(const QModelIndex& index);
	void edit2nd(const QModelIndex& index);

private:
	QPoint m_mousePoint;//鼠标位置
	int m_nType;//按钮状态:0-划过,1-按下
	QStringList m_btnNames;
};

/*QWComboBoxDelegate*/
class QWComboBoxDelegate : public QStyledItemDelegate
{
	Q_OBJECT
public:

	void setItems(QStringList items, bool isEdit);//初始化设置列表内容
	//创建编辑器
	QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index)
		const Q_DECL_OVERRIDE;
	//设置编辑器数据
	void setEditorData(QWidget* editor, const QModelIndex& index)const Q_DECL_OVERRIDE;
	//更新编辑器集合属性
	void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index)const Q_DECL_OVERRIDE;
	//设置模型数据
	void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)
		const Q_DECL_OVERRIDE;

	void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const;
private:

	QStringList m_ItemList;//选择列表
	bool m_isEdit;//是否可编辑
};

/*QWCheckBoxDelegate*/
class QWCheckBoxDelegate : public QStyledItemDelegate
{
	Q_OBJECT

public:
	/*QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index)
	const Q_DECL_OVERRIDE;
	void setEditorData(QWidget* editor, const QModelIndex& index)const Q_DECL_OVERRIDE;
	void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index)const Q_DECL_OVERRIDE;
	void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)
	const Q_DECL_OVERRIDE;*/
	void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
	bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);

};

/*QWLineEditDelegate*/
class QWLineEditDelegate : public QStyledItemDelegate
{
	Q_OBJECT

public:
	QWLineEditDelegate(QObject *parent = NULL);
	~QWLineEditDelegate();

	QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index)
		const Q_DECL_OVERRIDE;

	void setEditorData(QWidget* editor, const QModelIndex& index)const Q_DECL_OVERRIDE;
	void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index)const Q_DECL_OVERRIDE;
	void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)
		const Q_DECL_OVERRIDE;

	void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const;
};

/*QWIntSpinDelegate*/
class QWIntSpinDelegate : public QStyledItemDelegate
{
	Q_OBJECT
public:
	//QWIntSpinDelegate(QObject* parent = 0);

	QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index)
		const Q_DECL_OVERRIDE;

	void setEditorData(QWidget* editor, const QModelIndex& index)const Q_DECL_OVERRIDE;
	void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index)const Q_DECL_OVERRIDE;
	void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)
		const Q_DECL_OVERRIDE;

	void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const;
};

/*QWLineEditDelegate_IP*/
//继承QWLineEditDelegate并重写QWLineEditDelegate_IP
class QWLineEditDelegate_IP : public QWLineEditDelegate
{
	Q_OBJECT

public:

	QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index)
		const Q_DECL_OVERRIDE;

	void setEditorData(QWidget* editor, const QModelIndex& index)const Q_DECL_OVERRIDE;
};

QWControlDelegate.cpp

#include "QWControlDelegate.h"

#pragma execution_character_set("utf-8")

//QWPushButtonDelegate***************************************************************************************************************
void QWPushButtonDelegate::setItems(QStringList items)
{
	m_btnNames = items;
}
//绘制按钮
void QWPushButtonDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const
{
	QStyleOptionViewItem viewOption(option);
	initStyleOption(&viewOption, index);
	if (option.state.testFlag(QStyle::State_HasFocus))
		viewOption.state = viewOption.state^QStyle::State_HasFocus;
	QStyledItemDelegate::paint(painter, viewOption, index);

	//计算按钮显示区域
	int nCount = m_btnNames.count();
	int w = nCount != 0 ? option.rect.width() / nCount : 0;
	if (w < 0)
		return;

	for (int i = 0; i < nCount; i++)
	{
		//绘制按钮
		QStyleOptionButton button;
		button.rect = option.rect.adjusted(4 + i*w, 4, -(w*(nCount - i - 1) + 4), -4);
		button.text = m_btnNames.at(i);
		button.state |= QStyle::State_Enabled;

		if (button.rect.contains(m_mousePoint))
			if (m_nType == 0)
				button.state |= QStyle::State_MouseOver;
			else if (m_nType == 1)
				button.state |= QStyle::State_Sunken;

		QPushButton pushBtn;
		pushBtn.setStyleSheet("background-color:#072433;");
		pushBtn.style()->drawControl(QStyle::CE_PushButton, &button, painter, &pushBtn);
	}

}

//响应按钮事件 - 划过、按下
bool QWPushButtonDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
{
	m_nType = -1;
	bool bRepaint = false;
	QMouseEvent* pEvent = static_cast<QMouseEvent*>(event);
	m_mousePoint = pEvent->pos();

	int nCount = m_btnNames.count();

	int w = nCount != 0 ? option.rect.width() / nCount : 0;
	if (w < 0) {
		return false;
	}

	//还原鼠标样式
	//QApplication::restoreOverrideCursor();

	for (int i = 0; i < nCount; ++i)
	{
		QStyleOptionButton button;
		button.rect = option.rect.adjusted(4 + i*w, 4, -(w*(nCount - i - 1) + 4), -4);

		//鼠标位于按钮之上
		if (!button.rect.contains(m_mousePoint))
			continue;

		bRepaint = true;
		switch (event->type())
		{
			//鼠标划过
		case QEvent::MouseMove:
		{
			//设置鼠标样式为手型
			//QApplication::setOverrideCursor(Qt::PointingHandCursor);
			m_nType = 0;
			//QToolTip::showText(pEvent->globalPos(), m_btnNames.at(i));
			break;
		}

		//鼠标按下
		case QEvent::MouseButtonPress:
		{
			m_nType = 1;
			break;
		}

		//鼠标释放
		case QEvent::MouseButtonRelease:
		{
			switch (i)
			{
			case 0:
			{
				emit edit1st(index);
				break;
			}
			case 1:
			{
				emit edit2nd(index);
				break;
			}
			default:
				break;
			}
		}
		default:
			break;

		}
	}
	return bRepaint;
}

//QWComboBoxDelegate********************************************************************************************************************
void QWComboBoxDelegate::setItems(QStringList items, bool isEdit)
{
	m_ItemList = items;
	m_isEdit = isEdit;
}

QWidget* QWComboBoxDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
	Q_UNUSED(option);
	Q_UNUSED(index);
	//创建需要的控件进行返回
	QComboBox* editor = new QComboBox(parent);
	editor->setFrame(false);//设置为无边框
	for (int i = 0; i < m_ItemList.count(); i++) //从字符串列表初始下拉列表
	{
		editor->addItem(m_ItemList.at(i));
	}

	editor->setEditable(m_isEdit);//是否可编辑

	return editor;
}

void QWComboBoxDelegate::setEditorData(QWidget* editor, const QModelIndex& index)const
{
	QString text = index.model()->data(index, Qt::EditRole).toString();
	QComboBox* comboBox = static_cast<QComboBox*>(editor);
	int tindex = comboBox->findText(text);//通过显示文本内容得到当前的item
	comboBox->setCurrentIndex(tindex);
}

void QWComboBoxDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index)const
{
	QComboBox* comboBox = static_cast<QComboBox*>(editor);
	QString text = comboBox->currentText();//通过当前的索引得到文本内容
	model->setData(index, text, Qt::EditRole);
}

void  QWComboBoxDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)const
{
	//Q_UNUSED(index);
	editor->setGeometry(option.rect);//外观尺寸
}

void QWComboBoxDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const
{
	QStyleOptionViewItem newoption(option);
	newoption.displayAlignment = Qt::AlignCenter;
	QStyledItemDelegate::paint(painter, newoption, index);
}

//QWCheckBoxDelegate****************************************************************************************************************
static	QRect CheckBoxRect(const QStyleOptionViewItem& viewItemStyleOptions)
{
	//绘制按钮所需要的参数
	QStyleOptionButton checkBoxStyleOption;
	//按照给定的风格参数  返回元素子区域
	QRect checkBoxRect = QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkBoxStyleOption);
	//返回QCheckBox
	QPoint checkBoxPoint(viewItemStyleOptions.rect.x() + viewItemStyleOptions.rect.width() / 2 - checkBoxRect.width() / 2,
		viewItemStyleOptions.rect.y() + viewItemStyleOptions.rect.height() / 2 - checkBoxRect.height() / 2);
	//返回QCheckBox几何形状
	return QRect(checkBoxPoint, checkBoxRect.size());
}


void QWCheckBoxDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const
{
	bool checked = index.model()->data(index, Qt::DisplayRole).toBool();

	if (index.column() == 2) {
		//按钮的风格选项
		QStyleOptionButton checkBoxStyleOption;
		//|=为复合赋值语句,a|=b等价于a=a|b,对a和b进行位运算或运算
		checkBoxStyleOption.state |= QStyle::State_Enabled;
		//根据值判断是否选中
		checkBoxStyleOption.state |= checked ? QStyle::State_On : QStyle::State_Off;
		//返回QCheckBox几何形状
		checkBoxStyleOption.rect = CheckBoxRect(option);

		QCheckBox checkbtn;
		checkbtn.setStyleSheet("background-color:#072433;");
		//绘制QCheckBox
		QApplication::style()->drawControl(QStyle::CE_CheckBox, &checkBoxStyleOption, painter, &checkbtn);

	}
	else {
		//否则调用默认委托
		QStyledItemDelegate::paint(painter, option, index);
	}
}

bool QWCheckBoxDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index)
{
	if (index.column() == 16 | index.column() == 18) {
		if ((event->type() == QEvent::MouseButtonRelease) || (event->type() == QEvent::MouseButtonDblClick))
		{
			QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
			if (mouseEvent->button() != Qt::LeftButton || !CheckBoxRect(option).contains(mouseEvent->pos())) {
				return true;
			}
			if (event->type() == QEvent::MouseButtonDblClick) {
				return true;
			}
		}
		else if (event->type() == QEvent::KeyPress) {
			if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space&&static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select) {
				return false;
			}
		}
		else {
			return false;
		}
		bool checked = index.model()->data(index, Qt::DisplayRole).toBool();
		return model->setData(index, !checked, Qt::EditRole);
	}
	else {
		return QStyledItemDelegate::editorEvent(event, model, option, index);
	}
}

//QWLineEditDelegate************************************************************************************************************
QWLineEditDelegate::QWLineEditDelegate(QObject *parent)
	: QStyledItemDelegate(parent)
{
}

QWLineEditDelegate::~QWLineEditDelegate()
{
}

QWidget* QWLineEditDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
	QLineEdit* editor = new QLineEdit(parent);
	editor->setFrame(false);
	return editor;
}


void QWLineEditDelegate::setEditorData(QWidget* editor, const QModelIndex& index)const
{
	QString value = index.model()->data(index, Qt::EditRole).toString();
	QLineEdit* le = dynamic_cast<QLineEdit*>(editor);
	le->setText(value);
}

void QWLineEditDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index)const
{
	model->setData(index, dynamic_cast<QLineEdit*>(editor)->text(), Qt::EditRole);
}

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

void QWLineEditDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const
{
	QStyleOptionViewItem newoption(option);
	newoption.displayAlignment = Qt::AlignCenter;
	QStyledItemDelegate::paint(painter, newoption, index);
}

void QWLineEditDelegate_IP::setEditorData(QWidget* editor, const QModelIndex& index)const
{
	//将model中的数据显示在QTableView中
	QString value = index.model()->data(index, Qt::EditRole).toString();
	QLineEdit* le = dynamic_cast<QLineEdit*>(editor);
	le->setText(value);

	qDebug() << le->text();
	if(le->text()=="")
		le->setText("0.0.0.0");

	QStringList IPlist = le->text().split(".");
	if (IPlist.size() != 4)
		le->setText("0.0.0.0");
	qDebug() << le->text();
	QString ip;
	ip = "";

	for (int i = 0; i < IPlist.size(); i++) {
		bool issave = false;
		for (int j = 0; j < IPlist[i].length(); j++) {
			if (IPlist[i][j] == "0" && !issave)
				continue;
			else {
				issave = true;
				ip += IPlist[i][j];
			}
		}
		if(i<3)
			ip += ".";
		else if(i==3 && ip == "...")
			ip = "0.0.0.0";
	}


	le->setText(ip);
}

//QWIntSpinDelegate***********************************************************************************************************
QWidget* QWIntSpinDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
	QSpinBox* editor = new QSpinBox(parent);
	editor->setFrame(false);
	editor->setMinimum(0);
	editor->setMaximum(10000);
	return editor;
}

void QWIntSpinDelegate::setEditorData(QWidget* editor, const QModelIndex& index)const
{

	//从数据模型中获取数据,显示到代理组件中
	int value = index.model()->data(index, Qt::EditRole).toInt();
	QSpinBox* spinBox = static_cast<QSpinBox*>(editor);
	spinBox->setValue(value);

}

void QWIntSpinDelegate::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, Qt::EditRole);
}

void QWIntSpinDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index)const
{
	//设置组件大小
	editor->setGeometry(option.rect);
}

void QWIntSpinDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index)const
{
	QStyleOptionViewItem newoption(option);
	newoption.displayAlignment = Qt::AlignCenter;
	QStyledItemDelegate::paint(painter, newoption, index);
}

//IP重写**************************************************************************************************************************
QWidget* QWLineEditDelegate_IP::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
	QLineEdit* editor = new QLineEdit(parent);
	editor->setValidator(new QRegExpValidator(QRegExp("^(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.?(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.?(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\.?(1?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])|^\s*$"), parent));
	//editor->setInputMask("000.000.000.000");//;0表示删除时,默认填充0;并且使正则有效
	editor->setFrame(false);
	editor->setPlaceholderText("0.0.0.0");
	qDebug() << editor->text();
	
	return editor;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值