文章目录
概述
基本概念
简单文件目录浏览器【简单示例】
模型(Model)
自定义模型【示例】
视图(View)
表格数据显示【示例】
代理(Delegate)
利用Delegate设计表格控件【示例】
Qt的模型/视图结构分为三部分:模型(Model)、视图(View)和代理(Delegate)。其中,模型与数据源通信,并为其他部件提供接口;而视图从模型中获得用来引用数据条目的模型索引(Model Index)。在视图中,代理负责绘制数据条目,当编辑条目时,代理和模型直接进行通信。模型/视图/代理之间通过信号和槽进行通信,
概述
基本概念
- 模型(model)
InterView框架中的所有模型都基于抽象基类QAbstractItemModel类,此类由QProxyModel、 QAbstractListModel、 QAbstractTableModel、QAbstractProxyModel、 QDirModel、 QFileSystemModel、QHelpContentModel 和 QStandardItemModel类继承。其中, QAbstractListModel
类和QAbstractTableModel类是列表和表格模型的抽象基类,如果需要实现列表或表格模型,则应从这两个类继承。完成QStringList存储的QStringListModel继承自QAbstractListModel类,而与数据库有关的QSqlQueryModel类继承自QAbstractTableModel类; QAbstractProxyModel类是代理模型的抽象类;QDirModel类是文件和目录的存储模型。
- 视图(view)
InterView框架中的所有视图都基于抽象基类QAbstractItemView类,此类由QColumnView、 QHeaderView、 QListView、 QTableView和QTreeView类继承。其中, QListView类由QUndoView类和QListWidget类继承; QTableView类由QTableWidget类继承; QTreeView类由QTreeWidget类继承。而QListWidget类、QTableWidget类和QTreeWidget类实际上已经包含了数据,是模型/视图集成在一起的类。
- 代理(delegate)
InterView框架中的所有代理都基于抽象基类QAbstractItemDelegate类,此类由QItemDelegate 和 QStyledItemDelegate类继承。其中, QItemDelegate类由表示数据库中关系代理的QSqlRelationalDelegate类继承。
简单文件目录浏览器【简单示例】
简单实现一个文件目录浏览器。只需要编辑main.cpp文件在项目文件中即可。
- main.cpp
#include "mainwindow.h" #include <QApplication> #include <QAbstractItemModel> #include <QAbstractItemView> #include <QItemSelectionModel> #include <QDirModel> #include <QTreeView> #include <QListView> #include <QTableView> #include <QSplitter> int main(int argc, char *argv[]) { QApplication a(argc, argv); //新建一个QDirModel对象,为数据访问做准备,此外还可以设置过滤器。 //QDirmodel为访问本地文件系统提供数据模型,提供了新建、删除、创建目录等一系列与文件操作相关的函数。 QDirModel model; /* 新建三种不同的View对象,以便文件目录可以以三种不同的方式显示 */ QTreeView tree; QListView list; QTableView table; //调用setModel函数设置View对象的model为QDirmodel。 tree.setModel(&model); list.setModel(&model); table.setModel(&model); //设置QTreeView对象的选择方式为多选方式。 tree.setSelectionMode(QAbstractItemView::MultiSelection); //设置QListView对象与QTreeView对象使用相同的选择模型。 list.setSelectionModel(tree.selectionModel()); //设置QTableView对象与QTreeView对象使用相同的选择模型。 table.setSelectionModel(tree.selectionModel()); QObject::connect(&tree,SIGNAL(doubleClicked(QModelIndex)),&list, SLOT(setRootIndex(QModelIndex))); //实现双机对象中某一目录时显示此目录下的所以文件和目录,需要连接QTreeView对象的doubleClicked信号 //与QListView对象和QTableView对象的setRootIndex槽函数。 QObject::connect(&tree,SIGNAL(doubleClicked(QModelIndex)),&table, SLOT(setRootIndex(QModelIndex))); QSplitter *splitter = new QSplitter; splitter->addWidget(&tree); splitter->addWidget(&list); splitter->addWidget(&table); splitter->setWindowTitle(QObject::tr("Model/View")); splitter->show(); //MainWindow w; //w.show(); return a.exec(); }
- 执行结果
模型(Model)
通过实现将数值代码转换为文字的模型来介绍使用自定义模型。此模型中保存了不同军中的各种武器。
在model中会用到以下item主要的角色:
常量 描述
Qt::DisplayRole 显示文字
Qt::DecorationRole 绘制装饰数据(通常是图标)
Qt::EditRole 在编辑器中编辑的数据
Qt::ToolTipRole 工具提示
Qt::StatusTipRole 状态栏提示
Qt::WhatsThisRole What’s This文字
Qt::SizeHintRole 尺寸提示
Qt::FontRole 默认代理的绘制使用的字体
Qt::TextAlignmentRole 默认代理的对齐方式
Qt::BackgroundRole 默认代理的背景画刷
Qt::ForegroundRole 默认代理的前景画刷
Qt::CheckStateRole 默认代理的检查框状态
Qt::UserRole 用户自定义的数据的起始位置
自定义模型【示例】
- 项目结构
- main.cpp
#include "mainwindow.h" #include <QApplication> #include "modelex.h" #include <QTableView> int main(int argc, char *argv[]) { QApplication a(argc, argv); ModelEx modelEx; QTableView view; view.setModel(&modelEx); view.setWindowTitle(QObject::tr("modelEx")); view.resize(400,400); view.show(); //MainWindow w; //w.show(); return a.exec(); }
- modelex.h
#ifndef MODELEX_H #define MODELEX_H #include <QAbstractTableModel> #include <QVector> #include <QMap> #include <QStringList> class ModelEx : public QAbstractTableModel { public: explicit ModelEx(QObject *parent=0); //虚函数声明 //(a) virtual int rowCount(const QModelIndex &parent=QModelIndex()) const; virtual int columnCount(const QModelIndex &parent=QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role) const; signals: public slots: private: QVector<short> army; QVector<short> weaponType; QMap<short,QString> armyMap; //使用QMap数据结构保存“数值—文字”的映射 QMap<short,QString> weaponTypeMap; QStringList weapon; QStringList header; void populateModel(); //完成表格数据的初始化填充 }; #endif // MODELEX_H
- modelex.cpp
#include "modelex.h" ModelEx::ModelEx(QObject *parent):QAbstractTableModel(parent) { armyMap[1]=tr("空军"); armyMap[2]=tr("海军"); armyMap[3]=tr("陆军"); armyMap[4]=tr("海军陆战队"); weaponTypeMap[1]=tr("轰炸机"); weaponTypeMap[2]=tr("战斗机"); weaponTypeMap[3]=tr("航空母舰"); weaponTypeMap[4]=tr("驱逐舰"); weaponTypeMap[5]=tr("直升机"); weaponTypeMap[6]=tr("坦克"); weaponTypeMap[7]=tr("两栖攻击舰"); weaponTypeMap[8]=tr("两栖战车"); populateModel(); } void ModelEx::populateModel() { header<<tr("军种")<<tr("种类")<<tr("武器"); army<<1<<2<<3<<4<<2<<4<<3<<1; weaponType<<1<<3<<5<<7<<4<<8<<6<<2; weapon<<tr("B-2")<<tr("尼米兹级")<<tr("阿帕奇")<<tr("黄蜂级") <<tr("阿利伯克级")<<tr("AAAV")<<tr("M1A1")<<tr("F-22"); } int ModelEx::columnCount(const QModelIndex &parent) const { return 3; } int ModelEx::rowCount(const QModelIndex &parent) const { return army.size(); } QVariant ModelEx::data(const QModelIndex &index, int role) const { if(!index.isValid()) return QVariant(); if(role==Qt::DisplayRole) //(a) { switch(index.column()) { case 0: return armyMap[army[index.row()]]; break; case 1: return weaponTypeMap[weaponType[index.row()]]; break; case 2: return weapon[index.row()]; default: return QVariant(); } } return QVariant(); } QVariant ModelEx::headerData(int section, Qt::Orientation orientation, int role) const { if(role==Qt::DisplayRole&&orientation==Qt::Horizontal) return header[section]; return QAbstractTableModel::headerData(section,orientation,role); }
- 执行结果
视图(View)
通过自定义的view实现一个对TableModel的表格数据进行显示的柱状图统计图示例。
表格数据显示【示例】
- 项目结构
- main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
- mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QStandardItemModel> #include <QTableView> #include <QMenuBar> #include <QMenu> #include <QAction> #include <QSplitter> #include "histogramview.h" class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); void createAction(); void createMenu(); void setupModel(); void setupView(); void openFile(QString); public slots: void slotOpen(); private: QMenu *fileMenu; QAction *openAct; QStandardItemModel *model; QTableView *table; QSplitter *splitter; HistogramView *histogram; }; #endif // MAINWINDOW_H
- mainwindow.cpp
#include "mainwindow.h" #include <QItemSelectionModel> #include <QFileDialog> #include <QFile> #include <QTextStream> #include <QStringList> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { createAction(); createMenu(); setupModel(); setupView(); setWindowTitle(tr("View Example")); resize(600,600); } MainWindow::~MainWindow() { } void MainWindow::createAction() { openAct = new QAction(tr("打开"),this); connect(openAct,SIGNAL(triggered()),this,SLOT(slotOpen())); } void MainWindow::createMenu() { fileMenu = new QMenu(tr("文件"),this); fileMenu->addAction(openAct); menuBar()->addMenu(fileMenu); } void MainWindow::setupModel() { model = new QStandardItemModel(4,4,this); model->setHeaderData(0,Qt::Horizontal,tr("部门")); model->setHeaderData(1,Qt::Horizontal,tr("男")); model->setHeaderData(2,Qt::Horizontal,tr("女")); model->setHeaderData(3,Qt::Horizontal,tr("退休")); } void MainWindow::setupView() { /* table = new QTableView; //新建一个QTableView对象 table->setModel(model); //为QTableView对象设置相同的Model QItemSelectionModel *selectionModel=new QItemSelectionModel(model); //(a) table->setSelectionModel(selectionModel); connect(selectionModel,SIGNAL(selectionChanged(QItemSelection, ItemSelection)),table,SLOT(selectionChanged(QItemSelection,QItemSelection))); //(b) splitter = new QSplitter; splitter->setOrientation(Qt::Vertical); splitter->addWidget(table); setCentralWidget(splitter); */ splitter = new QSplitter; splitter->setOrientation(Qt::Vertical); histogram = new HistogramView(splitter); //新建一个HistogramView对象 histogram->setModel(model); //为HistogramView对象设置相同的Model table = new QTableView; table->setModel(model); QItemSelectionModel *selectionModel=new QItemSelectionModel (model); table->setSelectionModel(selectionModel); histogram->setSelectionModel(selectionModel); //(a) splitter->addWidget(table); splitter->addWidget(histogram); setCentralWidget(splitter); connect(selectionModel,SIGNAL(selectionChanged(QItemSelection,QItemSelection)),table,SLOT(selectionChanged(QItemSelection,QItemSelection))); connect(selectionModel,SIGNAL(selectionChanged(QItemSelection,QItemSelection)),histogram,SLOT(selectionChanged(QItemSelection,QItemSelection))); //(b) } void MainWindow::slotOpen() { QString name; name = QFileDialog::getOpenFileName(this,"打开",".","histogram files (*.txt)"); if (!name.isEmpty()) openFile(name); } void MainWindow::openFile(QString path) { if (!path.isEmpty()) { QFile file(path); if (file.open(QFile::ReadOnly | QFile::Text)) { QTextStream stream(&file); QString line; model->removeRows(0,model->rowCount(QModelIndex()), QModelIndex()); int row = 0; do { line = stream.readLine(); if (!line.isEmpty()) { model->insertRows(row, 1, QModelIndex()); 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(); } } }
- histogramview.h
#ifndef HISTOGRAMVIEW_H #define HISTOGRAMVIEW_H #include <QAbstractItemView> #include <QItemSelectionModel> #include <QRegion> #include <QMouseEvent> class HistogramView : public QAbstractItemView { Q_OBJECT public: HistogramView(QWidget *parent=0); //虚函数声明 QRect visualRect(const QModelIndex &index)const; void scrollTo(const QModelIndex &index,ScrollHint hint= EnsureVisible); QModelIndex indexAt(const QPoint &point)const; //为selections赋初值 void setSelectionModel(QItemSelectionModel *selectionModel); QRegion itemRegion(QModelIndex index); void paintEvent(QPaintEvent *); void mousePressEvent(QMouseEvent *event); protected slots: void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); protected: //虚函数声明 QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers); int horizontalOffset()const; int verticalOffset()const; bool isIndexHidden(const QModelIndex &index)const; void setSelection(const QRect &rect,QItemSelectionModel:: SelectionFlags flags);//(f) QRegion visualRegionForSelection(const QItemSelection &selection) const; private: QItemSelectionModel *selections; //(g) QList<QRegion> MRegionList; //(h) QList<QRegion> FRegionList; QList<QRegion> SRegionList; }; #endif // HISTOGRAMVIEW_H
- histogramview.cpp
#include "histogramview.h" #include <QPainter> HistogramView::HistogramView(QWidget *parent):QAbstractItemView(parent) { } // paintEvent()函数具体完成柱状统计图绘制的工作 void HistogramView::paintEvent(QPaintEvent *) { QPainter painter(viewport()); //(a) painter.setPen(Qt::black); int x0=40; int y0=250; /* 完成了x、y坐标轴的绘制,并标注坐标轴的变量 */ //y坐标轴 painter.drawLine(x0,y0,40,30); painter.drawLine(38,32,40,30); painter.drawLine(40,30,42,32); painter.drawText(20,30,tr("人数")); for(int i=1;i<5;i++) { painter.drawLine(-1,-i*50,1,-i*50); painter.drawText(-20,-i*50,tr("%1").arg(i*5)); } //x 坐标轴 painter.drawLine(x0,y0,540,250); painter.drawLine(538,248,540,250); painter.drawLine(540,250,538,252); painter.drawText(545,250,tr("部门")); int posD=x0+20; int row; for(row=0;row<model()->rowCount(rootIndex());row++) { QModelIndex index=model()->index(row,0,rootIndex()); QString dep=model()->data(index).toString(); painter.drawText(posD,y0+20,dep); posD+=50; } /* 完成了表格第1列数据的柱状统计图的绘制 */ //男 int posM=x0+20; MRegionList.clear(); for(row=0;row<model()->rowCount(rootIndex());row++) { QModelIndex index=model()->index(row,1,rootIndex()); int male=model()->data(index).toDouble(); int width=10; if(selections->isSelected(index)) //(b) painter.setBrush(QBrush(Qt::blue,Qt::Dense3Pattern)); else painter.setBrush(Qt::blue); painter.drawRect(QRect(posM,y0-male*10,width,male*10));//(c) QRegion regionM(posM,y0-male*10,width,male*10); MRegionList.insert(row,regionM); //(d) posM+=50; } /* 完成了表格第2列数据的柱状统计图的绘制 */ //(e) //女 int posF=x0+30; FRegionList.clear(); for(row=0;row<model()->rowCount(rootIndex());row++) { QModelIndex index=model()->index(row,2,rootIndex()); int female=model()->data(index).toDouble(); int width=10; if(selections->isSelected(index)) painter.setBrush(QBrush(Qt::red,Qt::Dense3Pattern)); else painter.setBrush(Qt::red); painter.drawRect(QRect(posF,y0-female*10,width,female*10)); QRegion regionF(posF,y0-female*10,width,female*10); FRegionList.insert(row,regionF); posF+=50; } /* 完成了表格第3列数据的柱状统计图的绘制 */ //(f) //退休 int posS=x0+40; SRegionList.clear(); for(row=0;row<model()->rowCount(rootIndex());row++) { QModelIndex index=model()->index(row,3,rootIndex()); int retire=model()->data(index).toDouble(); int width=10; if(selections->isSelected(index)) painter.setBrush(QBrush(Qt::green,Qt::Dense3Pattern)); else painter.setBrush(Qt::green); painter.drawRect(QRect(posS,y0-retire*10,width,retire*10)); QRegion regionS(posS,y0-retire*10,width,retire*10); SRegionList.insert(row,regionS); posS+=50; } } void HistogramView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { QAbstractItemView::dataChanged(topLeft,bottomRight); viewport()->update(); } void HistogramView::setSelectionModel(QItemSelectionModel *selectionModel) { selections=selectionModel; } void HistogramView::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) { viewport()->update(); } void HistogramView::mousePressEvent(QMouseEvent *event) { QAbstractItemView::mousePressEvent(event); setSelection(QRect(event->pos().x(),event->pos().y(),1,1),QItemSelectionModel::SelectCurrent); } void HistogramView::setSelection(const QRect &rect,QItemSelectionModel::SelectionFlags flags) { int rows = model()->rowCount(rootIndex()); //获取总行数 int columns = model()->columnCount(rootIndex()); //获取总列数 QModelIndex selectedIndex; for (int row=0; row<rows; ++row) { for (int column=1; column<columns; ++column) { QModelIndex index=model()->index(row,column,rootIndex()); QRegion region=itemRegion(index); if (!region.intersected(rect).isEmpty()) selectedIndex = index; } } if(selectedIndex.isValid()) selections->select(selectedIndex,flags); else { QModelIndex noIndex; selections->select(noIndex,flags); } } QModelIndex HistogramView::indexAt(const QPoint &point)const { QPoint newPoint(point.x(),point.y()); QRegion region; // 男 列 foreach(region,MRegionList) { if (region.contains(newPoint)) { int row = MRegionList.indexOf(region); QModelIndex index = model()->index(row,1,rootIndex()); return index; } } // 女 列 foreach(region,FRegionList) { if (region.contains(newPoint)) { int row = FRegionList.indexOf(region); QModelIndex index = model()->index(row,2,rootIndex()); return index; } } // 合计 列 foreach(region,SRegionList) { if (region.contains(newPoint)) { int row = SRegionList.indexOf(region); QModelIndex index = model()->index(row,3,rootIndex()); return index; } } return QModelIndex(); } QRect HistogramView::visualRect(const QModelIndex &index)const{} void HistogramView::scrollTo(const QModelIndex &index,ScrollHint){} QModelIndex HistogramView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers){} int HistogramView::horizontalOffset()const{} int HistogramView::verticalOffset()const{} bool HistogramView::isIndexHidden(const QModelIndex &index)const{} QRegion HistogramView::visualRegionForSelection(const QItemSelection & selection)const{} QRegion HistogramView::itemRegion(QModelIndex index) { QRegion region; if (index.column() == 1) //男 region = MRegionList[index.row()]; if (index.column() == 2) //女 region = FRegionList[index.row()]; if (index.column() == 3) //退休 region = SRegionList[index.row()]; return region; }
- 执行结果
代理(Delegate)
利用Delegate设计表格控件。
利用Delegate设计表格控件【示例】
- 项目结构
- main.cpp
#include "mainwindow.h" #include <QApplication> #include <QStandardItemModel> #include <QTableView> #include <QFile> #include <QTextStream> #include "datedelegate.h" #include "combodelegate.h" #include "spindelegate.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); 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); model.setHeaderData(0,Qt::Horizontal,QObject::tr("姓名")); model.setHeaderData(1,Qt::Horizontal,QObject::tr("生日")); model.setHeaderData(2,Qt::Horizontal,QObject::tr("职业")); model.setHeaderData(3,Qt::Horizontal,QObject::tr("收入")); QFile file("test.txt"); if(file.open(QFile::ReadOnly|QFile::Text)) { QTextStream stream(&file); QString line; model.removeRows(0,model.rowCount(QModelIndex()),QModelIndex()); int row =0; do{ line = stream.readLine(); if(!line.isEmpty()) { model.insertRows(row,1,QModelIndex()); 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(); //MainWindow w; //w.show(); return a.exec(); }
- spindelegate.h
#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
- spindelegate.cpp
#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); }
- datedelegate.h
#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; //(a) void setEditorData(QWidget *editor, const QModelIndex &index) const; //(b) void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; //将Delegate中对数据的改变更新至Model中 void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem & option, const QModelIndex &index) const; //更新控件区的显示 }; #endif // DATEDELEGATE_H
- datedelegate.cpp
#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); //(a) editor->setDisplayFormat("yyyy-MM-dd"); //(b) editor->setCalendarPopup(true); //(c) editor->installEventFilter(const_cast<DateDelegate*>(this)); //(d) return editor; } void DateDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const { QString dateStr= index.model()->data(index).toString(); //(a) QDate date = QDate::fromString(dateStr,Qt::ISODate); //(b) QDateTimeEdit *edit=static_cast<QDateTimeEdit*>(editor); //(c) edit->setDate(date); //设置控件的显示数据 } void DateDelegate::setModelData(QWidget *editor,QAbstractItemModel *model, const QModelIndex &index) const { QDateTimeEdit *edit=static_cast<QDateTimeEdit*>(editor);//(a) QDate date = edit->date(); //(b) model->setData(index,QVariant(date.toString(Qt::ISODate)));//(c) } void DateDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option,const QModelIndex &index) const { editor->setGeometry(option.rect); }
- combodelegate.h
#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
- combodelegate.cpp
#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); }
- 执行结果