qt中的委托-简单的应用
2016-06-07 19:24
399 查看
qt中表格的数据默认是无法编辑的,当在model的flag()函数中设置其可编辑后,双击数据可以通过lineEdit(qt默认的编辑器是一个有边框的lineEdit)对数据进行编辑,但有时我们希望数据可以通过用下拉框来选择或者其他的编辑器来编辑数据,或者我们希望通过鼠标点击此数据来触发某个事件达到修改数据的目的或者其他的什么目的。这时就要用到委托QstyleItemDelegate。
qt默认的编辑器的效果:
如果我们想要达到下拉框的效果:
必须要重写三个函数:
1.QWidget*createEditor() 告诉model用的是那个编辑器进行数据的编辑和选择
2.voidsetEditorData() 从model中读取数据,设置编辑器显示的数据
3.voidsetModelData( ) 从编辑器中读取当前显示的数据,设置model中的数据源
代码如下:
当表格中不同的地方要用不同的编辑器时,如下,zipcode列用自定义的ZipcodeSpinBox ,state列用下拉框。
代码如下:
mainWindow中:
还有一种是分开写的:
main函数中:
最后说一下paint功能和editEvent
paint可以绘制一些Qt没有提供的图形,下面举例:获取模型的数据,通过数据来改变进度条的显示
显示效果:
更具体的介绍可查看:http://qimo601.iteye.com/blog/1539147
委托中的editEvent用的比较少,主要是处理要通过像通过鼠标点击等来达到编辑的不同效果时用,但是事件是通过view后再传下来的,一般直接写到view的Event()中。
qt默认的编辑器的效果:
如果我们想要达到下拉框的效果:
必须要重写三个函数:
1.QWidget*createEditor() 告诉model用的是那个编辑器进行数据的编辑和选择
2.voidsetEditorData() 从model中读取数据,设置编辑器显示的数据
3.voidsetModelData( ) 从编辑器中读取当前显示的数据,设置model中的数据源
代码如下:
#include <QStyledItemDelegate> class QModelIndex; class QPainter; class QStyleOptionViewItem; class ItemDelegate : public QStyledItemDelegate { Q_OBJECT public: explicit ItemDelegate(QObject *parent=0) : QStyledItemDelegate(parent) {} 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; };对应的.cpp 文件中:
QWidget *ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { static QStringList usStates; if (usStates.isEmpty()) usStates << "(Unknown)" << "Alabama" << "Alaska" << "Arizona" << "Arkansas" << "California" << "Colorado" << "Connecticut" << "Delaware" << "District Of Columbia" << "Florida" << "Georgia"; QComboBox *editor = new QComboBox(parent); //设置好对应的编辑器,添加好其中的内容及其大小的边界限制等 editor->addItems(usStates); return editor; }
void ItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { //获取model数据源中的数据 QString state = index.model()->data(index).toString(); //获取编辑器-下拉框 QComboBox *comboBox = qobject_cast<QComboBox*>(editor); Q_ASSERT(comboBox); //设置编辑器的当前数据 comboBox->setCurrentIndex(comboBox->findText(state)); }
void ItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { //获取编辑器 QComboBox *comboBox = qobject_cast<QComboBox*>(editor); Q_ASSERT(comboBox); //将编辑器中的当前数据更改保存到model的数据源中 model->setData(index, comboBox->currentText()); }
当表格中不同的地方要用不同的编辑器时,如下,zipcode列用自定义的ZipcodeSpinBox ,state列用下拉框。
代码如下:
QWidget *ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { static QStringList usStates; if (usStates.isEmpty()) usStates << "(Unknown)" << "Alabama" << "Alaska" << "Arizona" << "Arkansas" << "California" << "Colorado" << "Connecticut" << "Delaware" << "District Of Columbia" << "Florida" << "Georgia" << "Hawaii" << "Idaho" << "Illinois" << "Indiana" << "Iowa" << "Kansas" << "Kentucky" << "Louisiana" << "Maine" << "Maryland" << "Massachusetts" << "Michigan" << "Minnesota" << "Mississippi" << "Missouri" << "Montana" << "Nebraska" << "Nevada" << "New Hampshire" << "New Jersey" << "New Mexico" << "New York" << "North Carolina" << "North Dakota" << "Ohio" << "Oklahoma" << "Oregon" << "Pennsylvania" << "Rhode Island" << "South Carolina" << "South Dakota" << "State" << "Tennessee" << "Texas" << "Utah" << "Vermont" << "Virginia" << "Washington" << "West Virginia" << "Wisconsin" << "Wyoming"; if (index.column() == Zipcode) return new ZipcodeSpinBox(parent); if (index.column() == State) { QComboBox *editor = new QComboBox(parent); editor->addItems(usStates); return editor; } return QStyledItemDelegate::createEditor(parent, option, index); } void ItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { if (index.column() == Zipcode) { int value = index.model()->data(index).toInt(); ZipcodeSpinBox *spinBox = qobject_cast<ZipcodeSpinBox*>(editor); Q_ASSERT(spinBox); spinBox->setValue(value); } else if (index.column() == State) { QString state = index.model()->data(index).toString(); QComboBox *comboBox = qobject_cast<QComboBox*>(editor); Q_ASSERT(comboBox); comboBox->setCurrentIndex(comboBox->findText(state)); } else QStyledItemDelegate::setEditorData(editor, index); } void ItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { if (index.column() == Zipcode) { ZipcodeSpinBox *spinBox = qobject_cast<ZipcodeSpinBox*>(editor); Q_ASSERT(spinBox); spinBox->interpretText(); model->setData(index, spinBox->value()); } else if (index.column() == State) { QComboBox *comboBox = qobject_cast<QComboBox*>(editor); Q_ASSERT(comboBox); model->setData(index, comboBox->currentText()); } else QStyledItemDelegate::setModelData(editor, model, index); }
mainWindow中:
tableView->setItemDelegate(new ItemDelegate(this));
还有一种是分开写的:
#ifndef COMBODELEGATE_H #define COMBODELEGATE_H #include <QItemDelegate> class ComboDelegate : public QItemDelegate { Q_OBJECT public: ComboDelegate(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 // COMBODELEGATE_H
#include "combodelegate.h" #include <QComboBox> ComboDelegate::ComboDelegate(QObject *parent) : QItemDelegate(parent) { } QWidget *ComboDelegate::createEditor(QWidget *parent,const QStyleOptionViewItem &/*option*/,const QModelIndex &/*index*/) const { QComboBox *editor = new QComboBox(parent); editor->addItem("工人"); editor->addItem("农民"); editor->addItem("医生"); editor->addItem("律师"); editor->addItem("军人"); editor->installEventFilter(const_cast<ComboDelegate*>(this)); return editor; } void ComboDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const { QString str =index.model()->data(index).toString(); QComboBox *box = static_cast<QComboBox*>(editor); int i=box->findText(str); box->setCurrentIndex(i); } void ComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QComboBox *box = static_cast<QComboBox*>(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); }
</pre><pre name="code" class="cpp"><pre name="code" class="cpp">#ifndef DATEDELEGATE_H #define DATEDELEGATE_H #include <QItemDelegate> 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
#include "datedelegate.h" #include <QDateTimeEdit> DateDelegate::DateDelegate(QObject *parent) : QItemDelegate(parent) { } QWidget *DateDelegate::createEditor(QWidget *parent,const QStyleOptionViewItem &/*option*/,const QModelIndex &/*index*/) const { QDateTimeEdit *editor = new QDateTimeEdit(parent); editor->setDisplayFormat("yyyy-MM-dd"); editor->setCalendarPopup(true); editor->installEventFilter(const_cast<DateDelegate*>(this)); return editor; } void DateDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const { QString dateStr= index.model()->data(index).toString(); QDate date = QDate::fromString(dateStr,Qt::ISODate); QDateTimeEdit *edit=static_cast<QDateTimeEdit*>(editor); edit->setDate(date); } void DateDelegate::setModelData(QWidget *editor,QAbstractItemModel *model, const QModelIndex &index) const { QDateTimeEdit *edit=static_cast<QDateTimeEdit*>(editor); QDate date = edit->date(); model->setData(index,QVariant(date.toString(Qt::ISODate))); } void DateDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index) const { editor->setGeometry(option.rect); }
#ifndef SPINDELEGATE_H #define SPINDELEGATE_H #include <QItemDelegate> class SpinDelegate : public QItemDelegate { Q_OBJECT public: SpinDelegate(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 // SPINDELEGATE_H
#include "spindelegate.h" #include <QSpinBox> SpinDelegate::SpinDelegate(QObject *parent): QItemDelegate(parent) { } QWidget *SpinDelegate::createEditor(QWidget *parent,const QStyleOptionViewItem &/*option*/,const QModelIndex &/*index*/) const { QSpinBox *editor = new QSpinBox(parent); editor->setRange(0,10000); editor->installEventFilter(const_cast<SpinDelegate*>(this)); return editor; } void SpinDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const { int value =index.model()->data(index).toInt(); QSpinBox *box = static_cast<QSpinBox*>(editor); box->setValue(value); } void SpinDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,const QModelIndex &index) const { QSpinBox *box = static_cast<QSpinBox*>(editor); int value = box->value(); model->setData(index,value); } void SpinDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const { editor->setGeometry(option.rect); }
main函数中:
QStandardItemModel model(4,4); QTableView tableView; tableView.setModel(&model); DateDelegate dateDelegate; tableView.setItemDelegateForColumn(1,&dateDelegate); ComboDelegate comboDelegate; tableView.setItemDelegateForColumn(2,&comboDelegate); SpinDelegate spinDelegate; tableView.setItemDelegateForColumn(3,&spinDelegate);
最后说一下paint功能和editEvent
paint可以绘制一些Qt没有提供的图形,下面举例:获取模型的数据,通过数据来改变进度条的显示
void ProgressBarDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { //绘制进度条 if(index.column() == 2) { //数据 int progress = index.model ()->data(index, Qt::DisplayRole).toInt (); //进度条 QStyleOptionProgressBarV2 progressBarOption; progressBarOption.state = QStyle:: State_Enabled; progressBarOption.direction = QApplication:: layoutDirection (); progressBarOption.rect = option.rect; progressBarOption.fontMetrics = QApplication:: fontMetrics (); progressBarOption.minimum = 0; progressBarOption.maximum = 100; progressBarOption.textAlignment = Qt:: AlignCenter; progressBarOption.textVisible = true; progressBarOption.progress = progress; progressBarOption.text = QString("%1%").arg(progressBarOption.progress); //上面的进度条是QtyleOption,需要通过此纯虚函数绘制 QApplication:: style ()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter); } else { return QItemDelegate::paint (painter, option, index); } }
显示效果:
更具体的介绍可查看:http://qimo601.iteye.com/blog/1539147
委托中的editEvent用的比较少,主要是处理要通过像通过鼠标点击等来达到编辑的不同效果时用,但是事件是通过view后再传下来的,一般直接写到view的Event()中。
相关文章推荐
- AS3自写类整理笔记 ClassLoader类第1/2页
- AS3自写类整理笔记 Dot类第1/2页
- DB2新手使用的一些小笔记:新建实例、数据库路径不存在、客户端连接 .
- perl脚本学习指南--读书笔记
- 《C++ primer plus》读书笔记(三)
- 《C++ primer plus》读书笔记(二)
- jquery 笔记 事件
- jqGrid 学习笔记整理――进阶篇(一 )
- VPS 配置优化笔记
- Ajax学习笔记整理
- 一千行的MySQL学习笔记汇总
- 两千行代码的PHP学习笔记汇总
- 用来记笔记的软件 EverNote 2.2.1.386提供下载
- Hibernate的学习笔记(3)
- 主主互备配合keepalived,MYSQL解决方案
- CentOS6.X下Docker安装笔记
- CentOS下Redis高可用安装笔记
- 在Flickr的开发与运维合作(笔记)
- Shell脚本学习笔记
- notes on python