Qt使用model/view 模式,一般来讲, model是数据,view把数据展示给用户,数据与界面的交互则通过delegagte来执行, 自定义的delegagte都继承于QItemDelegate类。
QItemDelegate类为模型中的数据项提供了显示和编辑的工具。QItemDelegate可以用来为基于QAbstractItemView子类的项目视图,提供自定义的显示特性和编辑器小控件。
该类提供了在view中绘制model数据的默认实现。在QAbstractItemDelegate(该类的基类)中,已经定义了paint()和sizeHint()这两个虚函数,为了确保delegate实现自定义的view,我们可以在子类中重新实现这些虚函数,来实现自定义的外观。
用户实现代理类时,可以从两个类中继承
第一种:从QAbstractItemDelegate类中继承,至少需要实现两个函数,paint()和sizeHint()
- void MyDelegate::paint(QPainter*painter,const QStyleOptionViewItem&option, constQModelIndex&index)const
- {
- if (index.column() == 需代理的列) {
- int content = index.model()->data(index, Qt::DisplayRole).toInt(); // 取到模型中原来的内容
- // ... 修改取到的值,代码略 QStyleOptionViewItem myOption = option;
- myOption.displayAlignment = Qt::AlignRight | Qt::AlignVCenter; // 处理文本的对齐方式 (不重要)
-
- drawDisplay(painter, myOption, myOption.rect, 修改后的值); // 写回处理后的值
- drawFocus(painter, myOption, myOption.rect); // 如果当前项具有焦点,它就绘制一个焦点矩形(不重要)
- } else{
- QItemDelegate::paint(painter, option, index);
- }
- }
-
- QSize MyDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
- {
- if (条件) {
- return Qsize(int width, int height); // 用户定义
- } else {
- return QStyledItemDelegate::sizeHint(option, index);
- }
- }
第二种:从QItemDelegate类继承,一般使用这种方式,减少代码量
- #ifndef DATEDELEGATE_H
- #define DATEDELEGATE_H
-
- #include
- #include
- #include
- #include
- #include
-
- class dateDelegate : public QItemDelegate
- {
- Q_OBJECT
-
- public:
- dateDelegate(QObject *parent = 0);
-
- // //创建委托控件
- 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 // DATEDELEGATE_H
自定义表格控件,目录如下
main.cpp
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
-
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
-
- //The QStandardItemModel class provides a generic model for storing custom data
- QStandardItemModel model(4, 4);
-
- QTableView tableView;
- tableView.setModel(&model);
-
- dateDelegate datedelegate;
- ComboboxDelegate combbDelegate;
- SpinBoxDelegate spinDelegate;
-
- tableView.setItemDelegateForColumn(1, &datedelegate);
- tableView.setItemDelegateForColumn(2, &combbDelegate);
- tableView.setItemDelegateForColumn(3, &spinDelegate);
- //View的setItemDelegateForColumn()函数为指定的列应用指定的Delegate
- model.setHeaderData(0, Qt::Horizontal, QObject::tr("Name"));
- model.setHeaderData(1, Qt::Horizontal, QObject::tr("Birthday"));
- model.setHeaderData(2, Qt::Horizontal, QObject::tr("job"));
- model.setHeaderData(3, Qt::Horizontal, QObject::tr("Income"));
-
-
- //为表格的表头显示进行设置
- QFile file(":/txt/data.txt");
-
- if (file.open(QFile::ReadOnly))
- {
- QTextStream stream(&file);
- QString line;
- int row = 0;
- do {
- line = stream.readLine();
- if (!line.isEmpty())
- {
- QStringList pieces = line.split(",", QString::SkipEmptyParts);
- model.setData(model.index(row, 0, QModelIndex()), pieces.value(0));
- model.setData(model.index(row, 1, QModelIndex()), pieces.value(1));
- model.setData(model.index(row, 2, QModelIndex()), pieces.value(2));
- model.setData(model.index(row, 3, QModelIndex()), pieces.value(3));
-
- row++;
- }
- } while (!line.isEmpty());
- file.close();
- }
- tableView.setWindowTitle(QObject::tr("Delegate"));
- tableView.show();
-
-
- return a.exec();
- }
spinboxdelegate.h
- #ifndef SPINBOXDELEGATE_H
- #define SPINBOXDELEGATE_H
-
- #include
- #include
-
- class SpinBoxDelegate : public QItemDelegate
- {
- Q_OBJECT
- public:
- explicit SpinBoxDelegate(QObject *parent = 0);
- 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 // SPINBOXDELEGATE_H
spinboxdelegate.cpp
- #include "spinboxdelegate.h"
-
- SpinBoxDelegate::SpinBoxDelegate(QObject *parent) :
- QItemDelegate(parent)
- {
- }
-
- QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
- const QModelIndex &index) const{
- QSpinBox * spinbox = new QSpinBox(parent);
- spinbox->setRange(1000,10000);
- spinbox->installEventFilter(const_cast
(this)); - return spinbox;
- }
-
- //将model中的数据赋值到控件上去
- void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const{
- int value = index.model()->data(index).toInt();
- QSpinBox * spin = static_cast
(editor); - spin->setValue(value);
- }
-
- //更新model中的数据
- void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
- const QModelIndex &index) const{
- QSpinBox * spin = static_cast
(editor); - int value = spin->value();
- model->setData(index,value);
- }
- void SpinBoxDelegate::updateEditorGeometry(QWidget *editor,
- const QStyleOptionViewItem &option, const QModelIndex &index) const{
- editor->setGeometry(option.rect);
- }
运行
代码:
https://github.com/Jelly-123/QT/tree/master/Delegate
参考: