#ifndef PERSONDELEGATE_H
#define PERSONDELEGATE_H
#include <QModelIndex>
#include <QSize>
#include <QSqlRelationalDelegate>
QT_FORWARD_DECLARE_CLASS(QPainter)
QT_FORWARD_DECLARE_CLASS(QAbstractItemModel)
class PersonDelegate : public QSqlRelationalDelegate
{
public:
PersonDelegate(QObject *parent);
~PersonDelegate(void);
//重写绘制单元格虚函数
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
//重写创建编辑器虚函数
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;
};
#endif
#include "PersonDelegate.h"
#include <QtGui>
PersonDelegate::PersonDelegate(QObject *parent)
: QSqlRelationalDelegate(parent)
{
}
PersonDelegate::~PersonDelegate(void)
{
}
void PersonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (index.column() != 3)
return QSqlRelationalDelegate::paint(painter, option, index);//调用基类的绘制方法
//第三列是性别列 数据库中存储的是1或2 分别代表男/女,这里需要获取模型的值后转换为文字显示在表格中.
const QAbstractItemModel *model = index.model();//获取模型
int nSex = model->data(index, Qt::DisplayRole).toInt();
int x = option.rect.x();
int y = option.rect.y() + 20;
painter->drawText(x, y, nSex == 1 ? tr("男") : tr("女"));
drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1));
}
QWidget *PersonDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (index.column() != 3)
return QSqlRelationalDelegate::createEditor(parent, option, index);
QComboBox *cb = new QComboBox(parent);
cb->setFrame(false);
cb->addItem(tr("男"));
cb->addItem(tr("女"));
return cb;
}
void PersonDelegate::setEditorData(QWidget * editor, const QModelIndex & index ) const
{
if(index.column() != 3)
return QSqlRelationalDelegate::setEditorData(editor, index);
QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
if(comboBox)
{
int i = index.model()->data(index, Qt::EditRole).toInt() - 1;
comboBox->setCurrentIndex(i);
}
}
void PersonDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const
{
if(index.column() != 3)
return QItemDelegate::setModelData(editor, model, index);
QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
if(comboBox)
{
model->setData(index, comboBox->currentIndex() + 1);
}
}
将自定义的代理类与TableView绑定:
ui.tableView->setItemDelegate(new PersonDelegate(ui.tableView));
//****************使用自定义的Widget来编辑数据单元格*****************************
//代理类头文件
class PersonDelegate : public QSqlRelationalDelegate
{
public:
PersonDelegate(QObject *parent);
~PersonDelegate(void);
//重写绘制单元格虚函数
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
//重写创建编辑器虚函数
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;
};
//代理类实现
void PersonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (index.column() != 3)
return QSqlRelationalDelegate::paint(painter, option, index);//调用基类的绘制方法
//第三列是性别列 数据库中存储的是1或2 分别代表男/女,这里需要获取模型的值后转换为文字显示在表格中.
const QAbstractItemModel *model = index.model();//获取模型
int nSex = model->data(index, Qt::DisplayRole).toInt();
int x = option.rect.x();
int y = option.rect.y() + 20;
painter->drawText(x, y, nSex == 1 ? tr("男") : tr("女"));
drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1));
}
QWidget *PersonDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
if (index.column() != 3)
return QSqlRelationalDelegate::createEditor(parent, option, index);
SexSelctor* slt = new SexSelctor(parent);
return slt;
}
void PersonDelegate::setEditorData(QWidget * editor, const QModelIndex & index ) const
{
if(index.column() != 3)
return QSqlRelationalDelegate::setEditorData(editor, index);
SexSelctor* slt = qobject_cast<SexSelctor*>(editor);
if(slt)
{
int i = index.model()->data(index, Qt::EditRole).toInt();
slt->setInitSex((SexEnum)(i));
}
}
void PersonDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const
{
if(index.column() != 3)
return QSqlRelationalDelegate::setModelData(editor, model, index);
SexSelctor* slt = qobject_cast<SexSelctor*>(editor);
if(slt)
{
model->setData(index, (int)(slt->getSex()));
}
}
void PersonDelegate::updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const
{
if(index.column() != 3)
return QSqlRelationalDelegate::updateEditorGeometry(editor, option, index);
SexSelctor* slt = qobject_cast<SexSelctor*>(editor);
if(slt)
{
QPoint pnt = editor->cursor().pos();
slt->setGeometry(pnt.x(), pnt.y(), 125, 125);
}
}
//自定义Widget头文件
enum SexEnum{seMan = 1, seWoman};
class SexSelctor : public QWidget
{
Q_OBJECT
public:
SexSelctor(QWidget *parent);
~SexSelctor();
void setInitSex(SexEnum sex);
SexEnum getSex(void);
private:
QRadioButton * rbMan;
QRadioButton * rbWoman;
QPushButton * pbOk;
QPushButton * pbCancel;
public slots:
void RadioButtonClicked();
};
//自定义Widget实现
SexSelctor::SexSelctor(QWidget *parent)
: QWidget(parent)
{
rbMan = new QRadioButton(this);
rbMan->setText(tr("男"));
rbMan->setChecked(true);
rbWoman = new QRadioButton(this);
rbWoman->setText(tr("女"));
rbWoman->setChecked(false);
QVBoxLayout* vBoxLayout = new QVBoxLayout(this);
vBoxLayout->addWidget(rbMan);
vBoxLayout->addWidget(rbWoman);
this->setLayout(vBoxLayout);
QObject::connect(rbMan, SIGNAL(clicked()), this, SLOT(RadioButtonClicked()));
QObject::connect(rbWoman, SIGNAL(clicked()), this, SLOT(RadioButtonClicked()));
this->setWindowFlags(Qt::Window | Qt::SubWindow);
this->setStatusTip(tr("性别设置"));
}
SexSelctor::~SexSelctor()
{
}
void SexSelctor::setInitSex(SexEnum sex)
{
switch(sex)
{
case seMan:
rbMan->setChecked(true);
break;
case seWoman:
rbWoman->setChecked(true);
break;
}
}
SexEnum SexSelctor::getSex(void)
{
return (rbMan->isChecked() ? seMan : seWoman);
}
void SexSelctor::RadioButtonClicked()
{
this->hide();
}
这样就可以实现在编辑性别单元格的时候,弹出自定义的Widget,实现灵活的界面控制.