收藏 分销(赏)

第8章-Qt-5模型视图结构.ppt

上传人:精**** 文档编号:14412513 上传时间:2026-09-11 格式:PPT 页数:43 大小:5.55MB 下载积分:8 金币
下载 相关
第8章-Qt-5模型视图结构.ppt_第1页
第1页 / 共43页
第8章-Qt-5模型视图结构.ppt_第2页
第2页 / 共43页


点击查看更多>>
资源描述
Click to edit Master title style,Click to edit Master text styles,Second level,Third level,Fourth level,Fifth level,*,*,单击此处编辑母版标题样式,*,*,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,*,第8章 Qt 5模型视图结构,第8章 Qt 5模型视图结构第8章 Qt 5模型视图结构Qt的模型/视图结构分为三部分:模型(Model)、视图(View)和代理(Delegate)。其中,模型与数据源通信,并为其他部件提供接口;而视图从模型中获得用来引用数据条目的模型索引(Model Index)。在视图中,代理负责绘制数据条目,当编辑条目时,代理和模型直接进行通信。模型/视图/代理之间通过信号和槽进行通信,如图8.1所示。,第一页,共43页。,Qt的模型/视图结构分为三部分:模型(Model)、视图(View)和代理(Delegate)。其中,模型与数据源通信,并为其他部件提供接口;而视图从模型中获得用来引用数据条目的模型索引(Model Index)。在视图中,代理负责绘制数据条目,当编辑条目时,代理和模型直接进行通信。模型/视图/代理之间通过信号和槽进行通信,如图8.1所示。,第二页,共43页。,8.1,概述,8.1.1,基本概念,1,模型(,Model,),InterView,框架中的所有模型都基于抽象基类,QAbstractItemModel,类,此类由,QProxyModel,、,QAbstractListModel,、,QAbstractTableModel,、,QAbstractProxyModel,、,QDirModel,、,Q,、,QHelpContentModel,和,QStandardItemModel,类继承。其中,,QAbstractListModel,类和,QAbstractTableModel,类是列表和表格模型的抽象基类,如果需要实现列表或表格模型,则应从这两个类继承。,第三页,共43页。,8.1.1,基本概念,2,视图(,View,),InterView,框架中的所有视图都基于抽象基类,QAbstractItemView,类,此类由,QColumnView,、,QHeaderView,、,QListView,、,QTableView,和,QTreeView,类继承。其中,,QListView,类由,QUndoView,类和,QListWidget,类继承;,QTableView,类由,QTableWidget,类继承;,QTreeView,类由,QTreeWidget,类继承。而,QListWidget,类、,QTableWidget,类和,QTreeWidget,类实际上已经包含了数据,是模型,/,视图集成在一起的类。,3,代理(,Delegate,),InterView,框架中的所有代理都基于抽象基类,QAbstractItemDelegate,类,此类由,QItemDelegate,和,QStyledItemDelegate,类继承。其中,,QItemDelegate,类由表示数据库中关系代理的,QSqlRelationalDelegate,类继承。,第四页,共43页。,8.1.2,【实例】:模型,/,视图类使用,【例】(简单),实现一个简单的文件目录浏览器,完成效果如图,8.2,所示。实例文件见光盘,CH801,。,创建工程“DirModeEx.pro”,,其源文件“main.cpp”中的具体代码。,最后运行结果如图8.2所示。,第五页,共43页。,8.2,模型(,Model,),【例】(难度一般),通过实现将数值代码转换为文字的模型来介绍如何使用自定义模型。此模型中保存了不同军种的各种武器,实现效果如图,8.3,所示。实例文件见光盘,CH802,。,第六页,共43页。,8.2,模型(,Model,),具体操作步骤如下。,(1)ModelEx类继承自QAbstractTableModel类,,头文件“modelex.h”中的具体代码。,(2),源文件“modelex.cpp”中的具体代码。,populateModel()函数的具体实现代码如下:,void ModelEx:populateModel(),headertr(军种)tr(种类)tr(武器);,army12342431;,weaponType13574862;,weapontr(B-2)tr(尼米兹级)tr(阿帕奇)tr(黄蜂级),tr(阿利伯克级)tr(AAAV)tr(M1A1)setHeaderData(0,Qt:Horizontal,tr(部门);,model-setHeaderData(1,Qt:Horizontal,tr(男);,model-setHeaderData(2,Qt:Horizontal,tr(女);,model-setHeaderData(3,Qt:Horizontal,tr(退休);,第十三页,共43页。,8.3,视图(,View,),setupView(),函数的具体实现代码如下:,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,QItemSelec-tion);/(b),splitter=new QSplitter;,splitter-setOrientation(Qt:Vertical);,splitter-addWidget(table);,setCentralWidget(splitter);,第十四页,共43页。,8.3,视图(,View,),(3)此时,运行效果如图8.5所示。,第十五页,共43页。,8.3,视图(,View,),(,1,)在头文件“,mainwindow.h,”中添加代码如下:,public:,void open);,public slots:,void slotOpen();,(,2,)在源文件,mainwindow.cpp,中添加代码如下:,#include,#include,#include,#include,其中,,在,createAction(),函数中添加代码如下:,connect(openAct,SIGNAL(triggered(),this,SLOT(slotOpen();,第十六页,共43页。,8.3,视图(,View,),槽函数,slotOpen(),完成打开标准文件对话框,具体代码如下:,void MainWindow:slotOpen(),QString name;,name=Q(this,打开,.,histogram files(*.txt);,if(!name.isEmpty(),open);,openFile(),函数完成,打开所选的文件内容,其具体实现代码,。,第十七页,共43页。,8.3,视图(,View,),新建一个文本文件,命名为“histogram.txt”,保存在项目D:QtCH8CH803 build-ViewEx-Desktop_Qt_5_4_0_MinGW_32bit-Debug目录下,文件内容及打开后的效果如图8.6所示。,第十八页,共43页。,8.3,视图(,View,),以上完成了表格数据的加载,下面介绍柱状统计图的绘制。,具体实现步骤如下。,(,1,)自定义,HistogramView,类继承自,QAbstractItemView,类,用于对表格数据进行柱状图显示。下面是,头文件“,histogramview.h,”的具体代码,。,(,2,)源文件“,histogramview.cpp,”的具体代码,。,dataChanged(),函数实现当,Model,中的数据更改时,调用绘图设备的,update(),函数进行,更新,反映数据的变化。具体实现代码,。,void HistogramView:dataChanged(const QModelIndex&topLeft,const QModelIndex&bottomRight),QAbstractItemView:dataChanged(topLeft,bottomRight);,viewport()-update();,setSelectionModel(),函数为,selections,赋初值,具体代码如下:,void HistogramView:setSelectionModel(QItemSelectionModel*selectionModel),selections=selectionModel;,第十九页,共43页。,8.3,视图(,View,),(3)下面的工作就是完成对选择项的更新。,selectionChanged()函数中完成当数据项发生变化时调用update()函数,重绘绘图设备即可工作。此函数是将其他View中的操作引起的数据项选择变化反映到自身View的显示中。具体代码如下:,void HistogramView:selectionChanged(const QItemSelection&selected,const QItemSelection&deselected),viewport()-update();,鼠标按下事件函数mousePressEvent(),在调用setSelection()函数时确定鼠标单击点是否在某个数据项的区域内,并设置选择项。具体代码如下:,void HistogramView:mousePressEvent(QMouseEvent*event),QAbstractItemView:mousePressEvent(event);,setSelection(QRect(event-pos().x(),event-pos().y(),1,1),QItem,Selec tionModel:SelectCurrent);,第二十页,共43页。,8.3,视图(,View,),setSelection(),函数的具体代码如下:,void HistogramView:setSelection(const QRect&rect,QItemSelectionModel,:SelectionFlags flags),int rows=model()-rowCount(rootIndex();/,获取总行数,int columns=model()-columnCount(rootIndex();/,获取总列数,QModelIndex selectedIndex;/(a),for(int row=0;rowrows;+row)/(b),for(int column=1;columnindex(row,column,rootIndex();,QRegion region=itemRegion(index);/(c),if(!region.intersected(rect).isEmpty(),selectedIndex=index;,if(selectedIndex.isValid()/(d),selections-select(selectedIndex,flags);,else,QModelIndex noIndex;,selections-select(noIndex,flags);,第二十一页,共43页。,8.3,视图(,View,),indexAt()函数的具体内容。,由于本例未用到以下函数的功能,所以没有实现具体内容,但仍然要写出函数体的框架,代码如下:,QRect HistogramView:visualRect(const QModelIndex&index)const,void HistogramView:scrollTo(const QModelIndex&index,ScrollHint),QModelIndex HistogramView:moveCursor(QAbstractItemView:CursorAction cursor Action,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,第二十二页,共43页。,8.3,视图(,View,),itemRegion()函数的具体代码如下:,QRegion HistogramView:itemRegion(QModelIndex index),QRegion region;,if(index.column()=1)/男,region=MRegionListindex.row();,if(index.column()=2)/女,region=FRegionListindex.row();,if(index.column()=3)/退休,region=SRegionListindex.row();,return region;,第二十三页,共43页。,8.3,视图(,View,),(,4,)在头文件“,mainwindow.h,”中添加代码如下:,#include histogramview.h,private:,HistogramView*histogram;,(,5,)在源文件“,mainwindow.cpp,”中添加代码,其中,,setupView(),函数的代码修改,。,(,6,)运行结果如图,8.4,所示。,第二十四页,共43页。,8.4,代理(,Delegate,),【例】(难度中等),利用,Delegate,设计表格中控件如图,8.7,所示。实例文件见光盘,CH804,。,第二十五页,共43页。,8.4,代理(,Delegate,),具体实现步骤如下。,(1)首先,加载表格数据,以便后面的操作。源文件“main.cpp”中的具体代码如下:,(2)选择“构建”“构建项目DateDelegate”菜单项,首先按照如图8.8所示的格式编辑本例所用的数据文件“test.txt”,保存在项目D:QtCH8CH804 build-DateDelegate-Desktop_Qt_5_4_0_MinGW_32bit-Debug目录下,然后运行程序,结果如图8.7所示。,第二十六页,共43页。,8.4,代理(,Delegate,),(,3,)在图,8.7,中,使用手动的方式实现对生日的录入编辑。下面使用日历编辑框,QDateTimeEdit,控件实现对生日的编辑,用自定义的,Delegate,来实现。,(,4,),DateDelegate,继承自,QItemDelegate,类。头文件“,datedelegate.h,”中的具体代码如下:,#include,class DateDelegate:public QItemDelegate,Q_OBJECT,public:,DateDelegate(QObject*parent=0);,QWidget*createEditor(QWidget*parent,const QStyleOptionViewItem/(a),void setEditorData(QWidget*editor,const QModelIndex/(b),void setModelData(QWidget*editor,QAbstractItemModel*model,const QModelIndex/,将,Delegate,中对数据的改变更新至,Model,中,void updateEditorGeometry(QWidget*editor,const QStyleOptionViewItem/,更新控件区的显示,;,第二十七页,共43页。,8.4,代理(,Delegate,),(,5,)源文件“,datedelegate.cpp,”中的具体代码如下:,#include datedelegate.h,#include,DateDelegate:DateDelegate(QObject*parent):,QItemDelegate(parent),createEditor(),函数的具体实现代码如下:,QWidget*DateDelegate:createEditor(QWidget*parent,const QStyleOption ViewItem&/*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(this);/(d),return editor;,第二十八页,共43页。,8.4,代理(,Delegate,),setEditorData()函数的具体代码如下:,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(editor);/(c),edit-setDate(date);/设置控件的显示数据,第二十九页,共43页。,8.4,代理(,Delegate,),setModelData()函数的具体代码如下:,void DateDelegate:setModelData(QWidget*editor,QAbstractItemModel*model,const QModelIndex&index)const,QDateTimeEdit*edit=static_cast(editor);/(a),QDate date=edit-date();/(b),model-setData(index,QVariant(date.toString(Qt:ISODate);/(c),updateEditorGeometry()函数的具体代码如下:,void DateDelegate:updateEditorGeometry(QWidget*editor,const QStyle OptionViewItem&option,const QModelIndex&index)const,editor-setGeometry(option.rect);,第三十页,共43页。,8.4,代理(,Delegate,),(6)在“main.cpp”文件中添加如下代码:,#include datedelegate.h,在语句tableView.setModel(后面添加如下代码:,DateDelegate dateDelegate;,tableView.setItemDelegateForColumn(1,(7)此时运行程序,双击第1行第2列,将显示如图8.9所示的日历编辑框控件。,第三十一页,共43页。,8.4,代理(,Delegate,),下面使用下拉列表框,QComboBox,控件实现对职业类型的输入编辑,使用自定义的,Delegate,实现。,(,1,),ComboDelegate,继承自,QItemDelegate,类。,头文件“,combodelegate.h,”中的具体代码如下:,#include,class ComboDelegate:public QItemDelegate,Q_OBJECT,public:,ComboDelegate(QObject*parent=0);,QWidget*createEditor(QWidget*parent,const QStyleOptionViewItem,void setEditorData(QWidget*editor,const QModelIndex,void setModelData(QWidget*editor,QAbstractItemModel*model,const QModelIndex,void updateEditorGeometry(QWidget*editor,const QStyleOptionViewItem,;,第三十二页,共43页。,8.4,代理(,Delegate,),(,2,)源文件“,combodelegate.cpp,”中的具体代码如下:,#include combodelegate.h,#include,ComboDelegate:ComboDelegate(QObject*parent):,QItemDelegate(parent),第三十三页,共43页。,8.4,代理(,Delegate,),createEditor()函数中创建了一个QComboBox控件,并插入可显示的条目,安装事件过滤器。具体代码如下:,QWidget*ComboDelegate:createEditor(QWidget*parent,const QStyleOption ViewItem&/*option*/,const QModelIndex&/*index*/)const,QComboBox*editor=new QComboBox(parent);,editor-addItem(工人);,editor-addItem(农民);,editor-addItem(医生);,editor-addItem(律师);,editor-addItem(军人);,editor-installEventFilter(const_cast(this);,return editor;,第三十四页,共43页。,8.4,代理(,Delegate,),setEditorData()函数中更新了Delegate控件中的数据显示,具体代码如下:,void ComboDelegate:setEditorData(QWidget*editor,const QModelIndex&index)const,QString str=index.model()-data(index).toString();,QComboBox*box=static_cast(editor);,int i=box-findText(str);,box-setCurrentIndex(i);,setModelData()函数中更新了Model中的数据,具体代码如下:,void ComboDelegate:setModelData(QWidget*editor,QAbstractItemModel*model,const QModelIndex&index)const,QComboBox*box=static_cast(editor);,QString str=box-currentText();,model-setData(index,str);,第三十五页,共43页。,8.4,代理(,Delegate,),updateEditorGeometry(),函数的具体代码如下:,void ComboDelegate:updateEditorGeometry(QWidget*editor,const QStyleOptionViewItem&option,const QModelIndex&/*index*/)const,editor-setGeometry(option.rect);,在“,main.cpp,”文件中添加以下内容:,#include combodelegate.h,在语句,tableView.setModel(&model),的后面添加以下代码:,ComboDelegate comboDelegate;,tableView.setItemDelegateForColumn(2,第三十六页,共43页。,8.4,代理(,Delegate,),此时运行程序,双击第1行第3列,显示如图8.10所示的下拉列表。,第三十七页,共43页。,8.4,代理(,Delegate,),下面使用,QSpinBox,控件实现对收入的输入编辑,调用自定义的,Delegate,来实现。,SpinDelegate,类的实现与,ComboDelegate,类的实现类似,此处不再详细讲解。,(,1,)头文件“,spindelegate.h,”中的具体代码如下:,#include,class SpinDelegate:public QItemDelegate,Q_OBJECT,public:,SpinDelegate(QObject*parent=0);,QWidget*createEditor(QWidget*parent,const QStyleOptionViewItem,void setEditorData(QWidget*editor,const QModelIndex,void setModelData(QWidget*editor,QAbstractItemModel*model,const QModelIndex,void updateEditorGeometry(QWidget*editor,const QStyleOptionViewItem,;,第三十八页,共43页。,8.4,代理(,Delegate,),(2)源文件“spindelegate.cpp”中的具体代码如下:,#include spindelegate.h,#include,SpinDelegate:SpinDelegate(QObject*parent):QItemDelegate(parent),createEditor()函数的具体实现代码如下:,QWidget*SpinDelegate:createEditor(QWidget*parent,const QStyleOption ViewItem&/*option*/,const QModelIndex&/*index*/)const,QSpinBox*editor=new QSpinBox(parent);,editor-setRange(0,10000);,editor-installEventFilter(const_cast(this);,return editor;,第三十九页,共43页。,8.4,代理(,Delegate,),setEditorData(),函数的具体实现代码如下:,void SpinDelegate:setEditorData(QWidget*editor,const QModelIndex&index)const,int value=index.model()-data(index).toInt();,QSpinBox*box=static_cast(editor);,box-setValue(value);,setModelData(),函数的具体实现代码如下:,void SpinDelegate:setModelData(QWidget*editor,QAbstractItemModel*model,const QModelIndex&index)const,QSpinBox*box=static_cast(editor);,int value=box-value();,model-setData(index,value);,第四十页,共43页。,8.4,代理(,Delegate,),updateEditorGeometry(),函数的具体实现代码如下:,void SpinDelegate:updateEditorGeometry(QWidget*editor,const QStyleOptionViewItem&option,const QModelIndex&/*index*/)const,editor-setGeometry(option.rect);,第四十一页,共43页。,8.4,代理(,Delegate,),(3)在“main.cpp”文件中添加代码如下:,#include spindelegate.h,在语句tableView.setModel(&model)的后面添加内容如下:,SpinDelegate spinDelegate;,tableView.setItemDelegateForColumn(3,(4)此时运行程序,双击第1行第4列后的效果如图8.11所示。,第四十二页,共43页。,谢谢观赏,第四十三页,共43页。,
展开阅读全文

开通  VIP、SVIP  下载更划算
下载10份以上建议开通 VIP 会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服