GitHub:https://github.com/mygit03/ModelDelegate.git
itemdelegate.h
#ifndef ITEMDELEGATE_H
#define ITEMDELEGATE_H
#include
#include
/*
* ReadOnly
*/
class ReadOnlyDelegate : public QItemDelegate
{
Q_OBJECT
public:
ReadOnlyDelegate(QObject *parent = 0): QItemDelegate(parent) {}
void setItems(QStringList items);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
return NULL;
}
};
/*
* ComboBox
*/
class ComboDelegate : public QItemDelegate
{
Q_OBJECT
public:
ComboDelegate(QObject *parent = 0);
void setItems(QStringList items);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
private:
QStringList m_sItemList;
};
/*
* DoubleSpinBox
*/
class SpinBoxDelegate : public QItemDelegate
{
Q_OBJECT
public:
SpinBoxDelegate(QObject *parent = 0);
void setRange(double min, double max);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
private:
double minValue;
double maxValue;
};
/*
* CheckBox
*/
class CheckBoxDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
CheckBoxDelegate(QObject *parent = 0);
void setColumn(int col);
protected:
void paint(QPainter* painter,const QStyleOptionViewItem& option,const QModelIndex& index) const;
bool editorEvent(QEvent *event,QAbstractItemModel *model,const QStyleOptionViewItem &option,const QModelIndex &index);
private:
int column; //设置复选框的列
};
#endif // ITEMDELEGATE_H
itemdelegate.cpp
#include "itemdelegate.h"
#include
#include
#include
#include
#include
#include
#include
/*
* ComboDelegate
*/
ComboDelegate::ComboDelegate(QObject *parent) :
QItemDelegate(parent)
{
}
//自定义下拉框列表项
void ComboDelegate::setItems(QStringList items)
{
m_sItemList = items;
}
QWidget *ComboDelegate::createEditor(QWidget *parent,const QStyleOptionViewItem &/*option*/,const QModelIndex &/*index*/) const
{
QComboBox *editor = new QComboBox(parent);
editor->addItems(m_sItemList);
editor->installEventFilter(const_cast(this));
return editor;
}
void ComboDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const
{
QString str =index.model()->data(index).toString();
QComboBox *box = static_cast(editor);
int i=box->findText(str);
box->setCurrentIndex(i);
}
void ComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox *box = static_cast(editor);
QString str = box->currentText();
model->setData(index,str);
}
void ComboDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const
{
editor->setGeometry(option.rect);
}
/*
* SpinBoxDelegate
*/
SpinBoxDelegate::SpinBoxDelegate(QObject *parent) :
QItemDelegate(parent)
{
//初始化最大最小值
minValue = 1.00;
maxValue = 100.00;
}
void SpinBoxDelegate::setRange(double min, double max)
{
minValue = min;
maxValue = max;
}
QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QDoubleSpinBox *editor = new QDoubleSpinBox(parent);
editor->setMinimum(minValue);
editor->setMaximum(maxValue);
editor->setSingleStep(0.01);
return editor;
}
void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
double value = index.model()->data(index, Qt::EditRole).toDouble();
QDoubleSpinBox *spinBox = static_cast (editor);
spinBox->setValue(value);
}
void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QDoubleSpinBox *spinBox = static_cast (editor);
spinBox->interpretText();
double 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);
}
/*
* CheckBoxDelegate
*/
static QRect CheckBoxRect(const QStyleOptionViewItem &viewItemStyleOptions)/*const*/
{
//绘制按钮所需要的参数
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());
}
CheckBoxDelegate::CheckBoxDelegate(QObject *parent):
QStyledItemDelegate(parent)
{
}
void CheckBoxDelegate::setColumn(int col)
{
column = col;
}
// 绘制复选框
void CheckBoxDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,const QModelIndex& index)const
{
bool checked = index.model()->data(index, Qt::DisplayRole).toBool();
if(index.column() == column){
QStyleOptionButton checkBoxStyleOption;
checkBoxStyleOption.state |= QStyle::State_Enabled;
checkBoxStyleOption.state |= checked? QStyle::State_On : QStyle::State_Off;
checkBoxStyleOption.rect = CheckBoxRect(option);
QApplication::style()->drawControl(QStyle::CE_CheckBox,&checkBoxStyleOption,painter);
}else{
QStyledItemDelegate::paint(painter, option, index);
}
}
// 响应鼠标事件,更新数据
bool CheckBoxDelegate::editorEvent(QEvent *event,
QAbstractItemModel *model,
const QStyleOptionViewItem &option,
const QModelIndex &index) {
if(index.column() == column){
if((event->type() == QEvent::MouseButtonRelease) ||
(event->type() == QEvent::MouseButtonDblClick)){
QMouseEvent *mouseEvent = static_cast(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(event)->key() != Qt::Key_Space &&
static_cast(event)->key() != Qt::Key_Select){
return false;
}
}else{
return false;
}
bool checked = index.model()->data(index, Qt::DisplayRole).toBool();
int data = checked ? 0 : 1; //互逆
return model->setData(index, data, Qt::EditRole);
}else{
return QStyledItemDelegate::editorEvent(event, model, option, index);
}
}
引用代码:
for(int col = 0; col < 4; ++col)
{
if(col == 0)
{
ReadOnlyDelegate *readOnly = new ReadOnlyDelegate;
setItemDelegateForColumn(col,readOnly);
}
if(col == 1)
{
CheckBoxDelegate *checkBox = new CheckBoxDelegate;
checkBox->setColumn(1);
setItemDelegateForColumn(col,checkBox);
}
if(col == 2)
{
SpinBoxDelegate *spinBox = new SpinBoxDelegate;
setItemDelegateForColumn(col,spinBox);
}
if(col == 3)
{
ComboDelegate *combo = new ComboDelegate;
combo->setItems(items);
setItemDelegateForColumn(col,combo);
}
for(int row = 0; row < 4; ++row)
{
QModelIndex index = model->index(row, col, QModelIndex());
model->setData(index, QString("%1%2").arg(row).arg(col));
}
}
参考文档:
学习记录-QTableView自定义委托实现QCheckBox复选框