QT数据库编程--定制TableView列

来源:互联网 发布:mac口红什么颜色好看 编辑:程序博客网 时间:2024/05/22 15:04
 从QSqlRelationalDelegate类继承一个类,并重写其虚方法,模拟性别字段编辑器,从整数转换为字符串下拉列表形式进行编辑或显示.

#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,实现灵活的界面控制.

原创粉丝点击