文章目录

  • 概述
    • 基本概念
      • 简单文件目录浏览器【简单示例】
  • 模型(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_OBJECTpublic: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对象设置相同的ModelQItemSelectionModel *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对象设置相同的Modeltable = 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));elsepainter.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));elsepainter.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));elsepainter.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);
}
  • 执行结果

Qt5入门学习——模型/视图结构相关推荐

  1. Qt5开发学习之模型/视图结构(十)

    Qt MVC概述 MVC是一种与用户界面相关的设计模式.通过使用此模型,可以有效地分离数据和用户界面.MVC设计模式包含三要素:表示数据的模型(Model).表示用户界面的视图(View)和定义了用户 ...

  2. pyqt5 qstring在哪个库_PyQt模型/视图结构编程示例:QStringListModel的用法

    引言 Python是一种面向对象的高级动态编程语言,相比于其它如C/C++语言,具有上手快.代码少.开发效率高的特点,Qt是跨平台的C++图形用户界面应用程序开发框架,是当前主流的GUI开发工具之一, ...

  3. 【Qt】模型/视图结构和数据绑定控件

    模型/视图结构 模型/视图是指处理数据的模型和向用户提供GUI的视图,这是从GUI分离数据的一种结构,又称为MVC(Model-View-Controller). 模型 QAbstractItemMo ...

  4. Qt中模型/视图结构

    8.1 概述 MVC设计模式是起源于Smalltalk的一种与用户界面相关的设计模式.通过使用此模型,可以有效地分离数据和用户界面.MVC设计模式包括三个元素:表示数据的模型 (Model).表示用户 ...

  5. Qt5模型/视图结构-视图(View)

    实现自定义的View,可继承自QAbstractItemView类,对所需的纯虚函数进行重定义与实现,对于QAbstractItemView类中的纯虚函数,在子类中必须进行重定义,但不一定要实现,可根 ...

  6. QT学习笔记14(Qt模型视图结构)

    一.基础知识 1.MVC设计模式:是一种与用户界面相关的设计模式,通过此模式,可以有效的分离数据和用户界面. MVC包括三个要素: 表示数据的模型(Model):应用程序的对象 表示用户界面的视图(V ...

  7. QT学习:模型/视图基本概念

    Qt的模型/视图结构分为三部分:模型(Model).视图(View)和代理(Delegate).其中,模型与数据源通信,并为其他部件提供接口:而视图从模型中获得用来引用数据条目的模型索引(Model ...

  8. 深度学习模型部署学习一

    深度学习模型部署 学习链接:模型部署入门教程(一):模型部署简介 写在前面: 本文档为学习上述链接的相关记录,基本内容一致,仅用于学习用途,若侵权请联系我删除 目   录 深度学习模型部署 1 为什么 ...

  9. SSM框架入门学习记录

    SSM框架入门学习记录 //项目结构 在这里插入图片描述 在这里插入图片描述 包名多种多样,命名习惯问题. 流程:Controller(接受请求)-->Service(biz)(bl)(写业务函 ...

最新文章

  1. Java数组的初始化
  2. OpenCV 4.5.3 发布!优化DNN等多个模块~
  3. Object Pascal 运算符,常量,变量
  4. Break,Continue,Return 傻傻分不清楚
  5. 51CTO博客移动化意味着什么?IT博主可以搞事情了!
  6. 记得重用layout
  7. 缺陷调研报告_工厂的缺陷的分析报告及产生原因
  8. Openstack 平台部署安装
  9. 创建华丽 UI 的 7条规则 第一部分 (2019年更新)
  10. iOS中 点击按钮无响应
  11. Android 6.0 动态权限申请注意事项
  12. 2013年c语言课后作业答案,大一C语言课后习题答案.doc
  13. Python openpyxl文档
  14. windows11中文语言包|windows11中文汉化包
  15. X79双cpu linux,Sandy Bridge-E处理器、X79芯片组详尽官方规格
  16. 酱爆如花四眼仔,周星驰金牌配角不止吴孟达,他们名字都没人知道
  17. linux内核api作用,内存管理 – Linux内核API get_unmapped_area
  18. Hadoop 1.x 和 Hadoop 2.x 有什么区别?
  19. 【国企招聘合集」 运维/java/架构师/前端
  20. 羊车门问题python程序_羊车门问题

热门文章

  1. Ubuntu下安装国际版qq
  2. linux环境编程 百度云,linux环境下使用百度云网盘
  3. 微信小程序, 长按加号 不断添加数量
  4. 安装flax INFO pip查看相关包版本兼容时间过长
  5. crawler爬虫java实例,Crawler4j快速入门实例
  6. ModeShape介绍
  7. 应届毕业生,对五险一金,薪酬待遇的理解
  8. npm yarn pnpm 发展历程
  9. YCM代码补全插件找不到c++头文件
  10. cocos creator之active