Qt中的委托通常都是继承自QStyledItemDelegate或者QItemDelegate,二者的区别主要在于绘制方式,QStyledItemDelegate会使用当前样式绘制,并且能够使用qss,因此在在自定义委托时,一般使用 QStyledItemDelegate作为基类。除此之外,二者基本没有区别,写法和用法都一样。
继承 QStyledItemDelegate需要实现以下几个函数:
- createEditor():returns the widget used to change data from the model and can be reimplemented to customize editing behavior.
- setEditorData(): provides the widget with data to manipulate.
- updateEditorGeometry():ensures that the editor is displayed correctly with respect to the item view.
- setModelData():returns updated data to the model.
virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
virtual void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
virtual void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
假设一个QTableView中,某一列的数据全是“选项一,选项二,选项三”中的任意一个选项,这种情况下就可以把这一列的代理设置成以QComboBox为基础的,每次修改数据时双击表格中的cell,出现下拉框来选择数据。详细代码如下:
nari_combodelegate.h
#ifndef NARI_COMBODELEGATE_H
#define NARI_COMBODELEGATE_H
class NARI_ComboDelegate : public QItemDelegate
{
Q_OBJECT
public:
NARI_ComboDelegate(const QStringList &items, QObject *parent = NULL);
~NARI_ComboDelegate();
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;
QStringList getItemStr();
private:
QStringList m_ls_itemtext;
};
#endif // NARI_COMBODELEGATE_H
nari_combodelegate.cpp
#include "nari_combodelegate.h"
NARI_ComboDelegate::NARI_ComboDelegate(const QStringList &items, QObject *parent) :
QItemDelegate(parent)
{
m_ls_itemtext = items;
}
NARI_ComboDelegate::~NARI_ComboDelegate(){ }
QWidget *NARI_ComboDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QComboBox *editor = new QComboBox(parent);
editor->addItems(m_ls_itemtext);
editor->setEditable(false);
return editor;
}
void NARI_ComboDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QString value = index.model()->data(index, Qt::EditRole).toString();
QComboBox *comboBox = static_cast<QComboBox*>(editor);
int icurIndex = comboBox->findText(value);
comboBox->setCurrentIndex(icurIndex);
}
void NARI_ComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
model->setData(index, dynamic_cast<QComboBox*>(editor)->currentText(), Qt::EditRole);
}
void NARI_ComboDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
QStringList NARI_ComboDelegate::getItemStr()
{
return m_ls_itemtext;
}
mainwindow.cpp
// ...
ui->tableView->setItemDelegateForColumn(0, new NARI_ComboDelegate(QStringList() << "Item1" << "Item2" << "Item3"));
// ...
其他委托示例
限制输入大小
nari_doubledelegate.h
#ifndef NARI_DOUBLEDELEGATE_H
#define NARI_DOUBLEDELEGATE_H
class NARI_DoubleDelegate : public QItemDelegate
{
Q_OBJECT
public :
NARI_DoubleDelegate(double minval, double maxval, QObject *parent = NULL);
~NARI_DoubleDelegate();
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 m_minval, m_maxval;
};
#endif // NARI_DOUBLEDELEGATE_H
nari_doubledelegate.cpp
#include "nari_doubledelegate.h"
NARI_DoubleDelegate::NARI_DoubleDelegate(double minval, double maxval, QObject *parent)
: QItemDelegate(parent)
{
m_minval = minval;
m_maxval = maxval;
}
NARI_DoubleDelegate::~NARI_DoubleDelegate(){ }
QWidget *NARI_DoubleDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QDoubleSpinBox *editor = new QDoubleSpinBox(parent);
editor->setToolTip(QString::number(m_minval) + " - " + QString::number(m_maxval));
editor->setMinimum(m_minval);
editor->setMaximum(m_maxval);
return editor;
}
void NARI_DoubleDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
double value = index.model()->data(index, Qt::EditRole).toDouble();
QDoubleSpinBox *spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
spinBox->setValue(value);
}
void NARI_DoubleDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QDoubleSpinBox *spinBox = dynamic_cast<QDoubleSpinBox*>(editor);
spinBox->interpretText();
int value = spinBox->value();
model->setData(index, value, Qt::EditRole);
}
void NARI_DoubleDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}
限制输入IP地址
nari_Ipdelegate.h
#ifndef NARI_IPDELEGATE_H
#define NARI_IPDELEGATE_H
class NARI_IpDelegate : public QItemDelegate
{
public:
NARI_IpDelegate(QObject *parent = NULL);
~NARI_IpDelegate();
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;
};
#endif // NARI_IPDELEGATE_H
nari_Ipdelegate.cpp
#include "nari_ipdelegate.h"
NARI_IpDelegate::NARI_IpDelegate(QObject *parent)
: QItemDelegate(parent)
{
}
NARI_IpDelegate::~NARI_IpDelegate(){ }
QWidget *NARI_IpDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QLineEdit *editor = new QLineEdit(parent);
editor->setValidator(new QRegExpValidator(QRegExp("^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$"), parent));
editor->setInputMask("000.000.000.000;0"); //必须加;0否则前面的正则表达式失效,;0”表示删除时默认填充为0
return editor;
}
void NARI_IpDelegate::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 NARI_IpDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
model->setData(index, dynamic_cast<QLineEdit*>(editor)->text(), Qt::EditRole);
}
void NARI_IpDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
editor->setGeometry(option.rect);
}