2023年全國(guó)碩士研究生考試考研英語(yǔ)一試題真題(含答案詳解+作文范文)_第1頁(yè)
已閱讀1頁(yè),還剩41頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、第8章 Qt 5模型/視圖結(jié)構(gòu),概述,模型(Model),視圖(View),代理(Delegate),,Qt的模型/視圖結(jié)構(gòu)分為三部分:模型(Model)、視圖(View)和代理(Delegate)。其中,模型與數(shù)據(jù)源通信,并為其他部件提供接口;而視圖從模型中獲得用來(lái)引用數(shù)據(jù)條目的模型索引(Model Index)。在視圖中,代理負(fù)責(zé)繪制數(shù)據(jù)條目,當(dāng)編輯條目時(shí),代理和模型直接進(jìn)行通信。模型/視圖/代理之間通過(guò)信號(hào)和槽進(jìn)行通信,如圖8.1

2、所示。,8.1 概述,8.1.1 基本概念1.模型(Model)InterView框架中的所有模型都基于抽象基類QAbstractItemModel類,此類由QProxyModel、QAbstractListModel、QAbstractTableModel、QAbstractProxyModel、QDirModel、QFileSystemModel、QHelpContentModel 和 QStandard

3、ItemModel類繼承。其中,QAbstractListModel類和QAbstractTableModel類是列表和表格模型的抽象基類,如果需要實(shí)現(xiàn)列表或表格模型,則應(yīng)從這兩個(gè)類繼承。,8.1.1 基本概念,2.視圖(View)InterView框架中的所有視圖都基于抽象基類QAbstractItemView類,此類由QColumnView、QHeaderView、QListView、QTableView和QTreeView類繼

4、承。其中,QListView類由QUndoView類和QListWidget類繼承;QTableView類由QTableWidget類繼承;QTreeView類由QTreeWidget類繼承。而QListWidget類、QTableWidget類和QTreeWidget類實(shí)際上已經(jīng)包含了數(shù)據(jù),是模型/視圖集成在一起的類。3.代理(Delegate)InterView框架中的所有代理都基于抽象基類QAbstractItemDelega

5、te類,此類由QItemDelegate 和 QStyledItemDelegate類繼承。其中,QItemDelegate類由表示數(shù)據(jù)庫(kù)中關(guān)系代理的QSqlRelationalDelegate類繼承。,8.1.2 【實(shí)例】:模型/視圖類使用,【例】(簡(jiǎn)單) 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的文件目錄瀏覽器,完成效果如圖8.2所示。實(shí)例文件見光盤CH801。,創(chuàng)建工程“DirModeEx.pro”,其源文件“main.cpp”中的具體

6、代碼。最后運(yùn)行結(jié)果如圖8.2所示。,8.2 模型(Model),【例】(難度一般) 通過(guò)實(shí)現(xiàn)將數(shù)值代碼轉(zhuǎn)換為文字的模型來(lái)介紹如何使用自定義模型。此模型中保存了不同軍種的各種武器,實(shí)現(xiàn)效果如圖8.3所示。實(shí)例文件見光盤CH802。,,8.2 模型(Model),具體操作步驟如下。(1)ModelEx類繼承自QAbstractTableModel類,頭文件“modelex.h”中的具體代碼。(2)源文件“modelex.cpp”中

7、的具體代碼。populateModel()函數(shù)的具體實(shí)現(xiàn)代碼如下:void ModelEx::populateModel(){ header<<tr("軍種")<<tr("種類")<<tr("武器"); army<<1<<2<<3<<4<<2<<4&

8、lt;<3<<1; weaponType<<1<<3<<5<<7<<4<<8<<6<<2; weapon<<tr("B-2")<<tr("尼米茲級(jí)")<<tr("阿帕奇")<<tr("黃蜂級(jí)&

9、quot;) <<tr("阿利伯克級(jí)")<<tr("AAAV")<<tr("M1A1")<<tr("F-22");},,,8.2 模型(Model),columnCount()函數(shù)中,模型的列固定為“3”,所以直接返回“3”。int ModelEx::columnCount(con

10、st QModelIndex &parent) const{ return 3; }rowCount()函數(shù)返回模型的行數(shù)。int ModelEx::rowCount(const QModelIndex &parent) const{ return army.size();}data()函數(shù)返回指定索引的數(shù)據(jù),即將數(shù)值映射為文字。,8.2 模型(Model),表8.1列出了Item主要的角色

11、及其描述。,,8.2 模型(Model),headerData()函數(shù)返回固定的表頭數(shù)據(jù),設(shè)置水平表頭的標(biāo)題,具體代碼如下:QVariant ModelEx::headerData(int section, Qt::Orientation orientation, int role) const{ if(role==Qt::DisplayRole&&orientation==Qt::Horizontal)

12、 return header[section]; return QAbstractTableModel::headerData(section,orientation,role);},,8.2 模型(Model),(3)在源文件“main.cpp”中,將模型和視圖關(guān)聯(lián),具體代碼如下:#include #include "modelex.h"#include int main(i

13、nt argc,char *argv[]){ QApplication a(argc,argv); ModelEx modelEx; QTableView view; view.setModel(&modelEx); view.setWindowTitle(QObject::tr("modelEx")); view.resize(400,400); v

14、iew.show(); return a.exec();}(4)運(yùn)行結(jié)果如圖8.3所示。,8.3 視圖(View),【例】(難度中等) 通過(guò)利用自定義的View,實(shí)現(xiàn)一個(gè)對(duì)TableModel的表格數(shù)據(jù)進(jìn)行顯示的柱狀統(tǒng)計(jì)圖例子,以此介紹如何應(yīng)用自定義的View。實(shí)現(xiàn)效果如圖8.4所示。實(shí)例文件見光盤CH803。,,8.3 視圖(View),具體實(shí)現(xiàn)步驟如下。(1)完成主窗體,以便顯示View的內(nèi)容。MainWindow

15、 類繼承自QMainWindow類,作為主窗體。以下是頭文件“mainwindow.h”的具體代碼。(2)下面是源文件“mainwindow.cpp”中的具體代碼。setupModel()函數(shù)新建一個(gè)Model,并設(shè)置表頭數(shù)據(jù),其具體實(shí)現(xiàn)代碼如下:void MainWindow::setupModel(){ model = new QStandardItemModel(4,4,this); model->s

16、etHeaderData(0,Qt::Horizontal,tr("部門")); model->setHeaderData(1,Qt::Horizontal,tr("男")); model->setHeaderData(2,Qt::Horizontal,tr("女")); model->setHeaderData(3,Qt::Horiz

17、ontal,tr("退休"));},,8.3 視圖(View),setupView()函數(shù)的具體實(shí)現(xiàn)代碼如下:void MainWindow::setupView(){ table = new QTableView;//新建一個(gè)QTableView對(duì)象 table->setModel(model);//為QTableView對(duì)象設(shè)置相同的Model QItemSele

18、ctionModel *selectionModel=new QItemSelectionModel(model);//(a) table->setSelectionModel(selectionModel); connect(selectionModel,SIGNAL(selectionChanged(QItemSelection, ItemSelection)),table,SLOT(selectionCha

19、nged(QItemSelection,QItemSelec-tion)));//(b) splitter = new QSplitter; splitter->setOrientation(Qt::Vertical); splitter->addWidget(table); setCentralWidget(splitter);},8.3 視圖(View),(3)此時(shí),運(yùn)行效果如圖8.

20、5所示。,,,,8.3 視圖(View),(1)在頭文件“mainwindow.h”中添加代碼如下:public: void openFile(QString);public slots: void slotOpen();(2)在源文件mainwindow.cpp中添加代碼如下:#include #include #include #include 其中,在createAction()函數(shù)中添加代碼如下:

21、connect(openAct,SIGNAL(triggered()),this,SLOT(slotOpen()));,,8.3 視圖(View),槽函數(shù)slotOpen()完成打開標(biāo)準(zhǔn)文件對(duì)話框,具體代碼如下:void MainWindow::slotOpen(){ QString name; name = QFileDialog::getOpenFileName(this,"打開",&quo

22、t;.","histogram files (*.txt)"); if (!name.isEmpty()) openFile(name);}openFile()函數(shù)完成打開所選的文件內(nèi)容,其具體實(shí)現(xiàn)代碼。,8.3 視圖(View),新建一個(gè)文本文件,命名為“histogram.txt”,保存在項(xiàng)目D:\Qt\CH8\CH803\ build-ViewEx-Desktop_Q

23、t_5_4_0_MinGW_32bit-Debug目錄下,文件內(nèi)容及打開后的效果如圖8.6所示。,,,,8.3 視圖(View),以上完成了表格數(shù)據(jù)的加載,下面介紹柱狀統(tǒng)計(jì)圖的繪制。具體實(shí)現(xiàn)步驟如下。(1)自定義HistogramView類繼承自QAbstractItemView類,用于對(duì)表格數(shù)據(jù)進(jìn)行柱狀圖顯示。下面是頭文件“histogramview.h”的具體代碼。(2)源文件“histogramview.cpp”的具體代碼

24、。dataChanged()函數(shù)實(shí)現(xiàn)當(dāng)Model中的數(shù)據(jù)更改時(shí),調(diào)用繪圖設(shè)備的update()函數(shù)進(jìn)行更新,反映數(shù)據(jù)的變化。具體實(shí)現(xiàn)代碼。void HistogramView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight){ QAbstractItemView::dataChanged(topLe

25、ft,bottomRight); viewport()->update();}setSelectionModel()函數(shù)為selections賦初值,具體代碼如下:void HistogramView::setSelectionModel(QItemSelectionModel *selectionModel){ selections=selectionModel;},,,8.3 視圖(View),(3

26、)下面的工作就是完成對(duì)選擇項(xiàng)的更新。selectionChanged()函數(shù)中完成當(dāng)數(shù)據(jù)項(xiàng)發(fā)生變化時(shí)調(diào)用update()函數(shù),重繪繪圖設(shè)備即可工作。此函數(shù)是將其他View中的操作引起的數(shù)據(jù)項(xiàng)選擇變化反映到自身View的顯示中。具體代碼如下:void HistogramView::selectionChanged(const QItemSelection &selected, const QItemSelectio

27、n &deselected){ viewport()->update();}鼠標(biāo)按下事件函數(shù)mousePressEvent(),在調(diào)用setSelection()函數(shù)時(shí)確定鼠標(biāo)單擊點(diǎn)是否在某個(gè)數(shù)據(jù)項(xiàng)的區(qū)域內(nèi),并設(shè)置選擇項(xiàng)。具體代碼如下:void HistogramView::mousePressEvent(QMouseEvent *event){ QAbstractItemView::mouseP

28、ressEvent(event); setSelection(QRect(event->pos().x(),event->pos().y(),1,1),QItemSelec tionModel::SelectCurrent);},,8.3 視圖(View),setSelection()函數(shù)的具體代碼如下:void HistogramView::setSelection(const QRect &rec

29、t,QItemSelectionModel::SelectionFlags flags){ int rows = model()->rowCount(rootIndex());//獲取總行數(shù) int columns = model()->columnCount(rootIndex());//獲取總列數(shù) QModelIndex selectedIndex;//(a) for (i

30、nt row=0; rowindex(row,column,rootIndex()); QRegion region=itemRegion(index);//(c) if (!region.intersected(rect).isEmpty()) selectedIndex = index; } } if(selected

31、Index.isValid())//(d) selections->select(selectedIndex,flags); else { QModelIndex noIndex; selections->select(noIndex,flags); }},,8.3 視圖(View),indexAt()函數(shù)的具體內(nèi)容。由于本例未用到以下函數(shù)的

32、功能,所以沒(méi)有實(shí)現(xiàn)具體內(nèi)容,但仍然要寫出函數(shù)體的框架,代碼如下:QRect HistogramView::visualRect(const QModelIndex &index)const{}void HistogramView::scrollTo(const QModelIndex &index,ScrollHint){}QModelIndex HistogramView::moveCursor(QAbstrac

33、tItemView::CursorAction cursor Action, Qt::KeyboardModifiers modifiers){}int HistogramView::horizontalOffset()const{}int HistogramView::verticalOffset()const{}bool HistogramView::isIndexHidden(const QModelIndex &i

34、ndex)const{}QRegion HistogramView::visualRegionForSelection(const QItemSelection & selection)const{},,8.3 視圖(View),itemRegion()函數(shù)的具體代碼如下:QRegion HistogramView::itemRegion(QModelIndex index){ QRegion region;

35、 if (index.column() == 1)//男 region = MRegionList[index.row()]; if (index.column() == 2)//女 region = FRegionList[index.row()]; if (index.column() == 3)//退休 region = SRegionList[ind

36、ex.row()]; return region;},,8.3 視圖(View),(4)在頭文件“mainwindow.h”中添加代碼如下:#include "histogramview.h"private: HistogramView *histogram;(5)在源文件“mainwindow.cpp”中添加代碼,其中,setupView()函數(shù)的代碼修改。(6)運(yùn)行結(jié)果如圖8.4所示。

37、,8.4 代理(Delegate),【例】(難度中等) 利用Delegate設(shè)計(jì)表格中控件如圖8.7所示。實(shí)例文件見光盤CH804。,8.4 代理(Delegate),具體實(shí)現(xiàn)步驟如下。(1)首先,加載表格數(shù)據(jù),以便后面的操作。源文件“main.cpp”中的具體代碼如下:(2)選擇“構(gòu)建”→“構(gòu)建項(xiàng)目"DateDelegate"”菜單項(xiàng),首先按照如圖8.8所示的格式編輯本例所用的數(shù)據(jù)文件“test.txt”,

38、保存在項(xiàng)目D:\Qt\CH8\CH804\ build- DateDelegate-Desktop_Qt_5_4_0_MinGW_32bit- Debug目錄下,然后運(yùn)行程序,結(jié)果如圖8.7所示。,,8.4 代理(Delegate),(3)在圖8.7中,使用手動(dòng)的方式實(shí)現(xiàn)對(duì)生日的錄入編輯。下面使用日歷編輯框QDateTimeEdit 控件實(shí)現(xiàn)對(duì)生日的編輯,用自定義的Delegate來(lái)實(shí)現(xiàn)。(4)DateDelegate 繼承自QIt

39、emDelegate類。頭文件“datedelegate.h”中的具體代碼如下:#include class DateDelegate : public QItemDelegate{ Q_OBJECTpublic: DateDelegate(QObject *parent = 0); QWidget *createEditor(QWidget *parent, const QStyleOptionViewI

40、tem & option, const QModelIndex &index) const;//(a) void setEditorData(QWidget *editor, const QModelIndex &index) const;//(b) void setModelData(QWidget *editor, QAbstractItemModel *model, const QM

41、odelIndex &index) const;//將Delegate中對(duì)數(shù)據(jù)的改變更新至Model中 void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem & option, const QModelIndex &index) const;//更新控件區(qū)的顯示};,,,8.4 代理(Delegate),(5

42、)源文件“datedelegate.cpp”中的具體代碼如下:#include "datedelegate.h"#include DateDelegate::DateDelegate(QObject *parent) : QItemDelegate(parent){}createEditor()函數(shù)的具體實(shí)現(xiàn)代碼如下:QWidget *DateDelegate::createEditor(QWi

43、dget *parent,const QStyleOption ViewItem &/*option*/,const QModelIndex &/*index*/) const{ QDateTimeEdit *editor = new QDateTimeEdit(parent);//(a) editor->setDisplayFormat("yyyy-MM-dd");

44、//(b) editor->setCalendarPopup(true);//(c) editor->installEventFilter(const_cast(this));//(d) return editor;},,8.4 代理(Delegate),setEditorData()函數(shù)的具體代碼如下:void DateDelegate::setEditorData(QWidge

45、t *editor, const QModelIndex &index) const{ QString dateStr= index.model()->data(index).toString();//(a) QDate date = QDate::fromString(dateStr,Qt::ISODate);//(b) QDateTimeEdit *edit=static_ca

46、st(editor);//(c) edit->setDate(date);//設(shè)置控件的顯示數(shù)據(jù)},,,8.4 代理(Delegate),setModelData()函數(shù)的具體代碼如下:void DateDelegate::setModelData(QWidget *editor,QAbstractItemModel *model, const QModelIndex &index) const{

47、 QDateTimeEdit *edit=static_cast(editor);//(a) QDate date = edit->date();//(b) model->setData(index,QVariant(date.toString(Qt::ISODate)));//(c)}updateEditorGeometry()函數(shù)的具體代碼如下:void DateDelegate::upd

48、ateEditorGeometry(QWidget *editor,const QStyle OptionViewItem &option,const QModelIndex &index) const{ editor->setGeometry(option.rect);},,,8.4 代理(Delegate),(6)在“main.cpp”文件中添加如下代碼:#include "dated

49、elegate.h"在語(yǔ)句tableView.setModel(&model);后面添加如下代碼:DateDelegate dateDelegate;tableView.setItemDelegateForColumn(1,&dateDelegate);(7)此時(shí)運(yùn)行程序,雙擊第1行第2列,將顯示如圖8.9所示的日歷編輯框控件。,,8.4 代理(Delegate),下面使用下拉列表框QComboBox

50、控件實(shí)現(xiàn)對(duì)職業(yè)類型的輸入編輯,使用自定義的Delegate實(shí)現(xiàn)。(1)ComboDelegate繼承自QItemDelegate類。頭文件“combodelegate.h”中的具體代碼如下:#include class ComboDelegate : public QItemDelegate{ Q_OBJECTpublic: ComboDelegate(QObject *parent = 0); QW

51、idget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex&index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; void setModelData(QWidget

52、 *editor, QAbstractItemModel *model, const QModelIndex &index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;};,,8.4 代理(Delegate)

53、,(2)源文件“combodelegate.cpp”中的具體代碼如下:#include "combodelegate.h"#include ComboDelegate::ComboDelegate(QObject *parent) : QItemDelegate(parent){},,8.4 代理(Delegate),createEditor()函數(shù)中創(chuàng)建了一個(gè)QComboBox控件,并插

54、入可顯示的條目,安裝事件過(guò)濾器。具體代碼如下:QWidget *ComboDelegate::createEditor(QWidget *parent,const QStyleOption ViewItem &/*option*/,const QModelIndex &/*index*/) const{ QComboBox *editor = new QComboBox(parent); editor

55、->addItem("工人"); editor->addItem("農(nóng)民"); editor->addItem("醫(yī)生"); editor->addItem("律師"); editor->addItem("軍人"); editor->installEventFil

56、ter(const_cast(this)); return editor;},,,8.4 代理(Delegate),setEditorData()函數(shù)中更新了Delegate控件中的數(shù)據(jù)顯示,具體代碼如下:void ComboDelegate::setEditorData(QWidget *editor,const QModelIndex &index) const{ QString str =index

57、.model()->data(index).toString(); QComboBox *box = static_cast(editor); int i=box->findText(str); box->setCurrentIndex(i);}setModelData()函數(shù)中更新了Model中的數(shù)據(jù),具體代碼如下:void ComboDelegate::setModelData(QWi

58、dget *editor, QAbstractItemModel *model, const QModelIndex &index) const{ QComboBox *box = static_cast(editor); QString str = box->currentText(); model->setData(index,str);},,,,8.4 代理(Delegate),u

59、pdateEditorGeometry()函數(shù)的具體代碼如下:void ComboDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const{ editor->setGeometry(option.rect);}在“mai

60、n.cpp”文件中添加以下內(nèi)容:#include "combodelegate.h"在語(yǔ)句tableView.setModel(&model)的后面添加以下代碼:ComboDelegate comboDelegate;tableView.setItemDelegateForColumn(2,&comboDelegate);,8.4 代理(Delegate),此時(shí)運(yùn)行程序,雙擊第1行第3列,顯

61、示如圖8.10所示的下拉列表。,,8.4 代理(Delegate),下面使用QSpinBox控件實(shí)現(xiàn)對(duì)收入的輸入編輯,調(diào)用自定義的Delegate來(lái)實(shí)現(xiàn)。SpinDelegate類的實(shí)現(xiàn)與ComboDelegate類的實(shí)現(xiàn)類似,此處不再詳細(xì)講解。(1)頭文件“spindelegate.h”中的具體代碼如下:#include class SpinDelegate : public QItemDelegate{ Q_OB

62、JECTpublic: SpinDelegate(QObject *parent = 0); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const Q

63、ModelIndex &index) const; void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,

64、const QModelIndex &index) const;};,,,8.4 代理(Delegate),(2)源文件“spindelegate.cpp”中的具體代碼如下:#include "spindelegate.h"#include SpinDelegate::SpinDelegate(QObject *parent): QItemDelegate(parent){}createEdi

65、tor()函數(shù)的具體實(shí)現(xiàn)代碼如下:QWidget *SpinDelegate::createEditor(QWidget *parent,const QStyleOption ViewItem &/*option*/,const QModelIndex &/*index*/) const{ QSpinBox *editor = new QSpinBox(parent); editor->setR

66、ange(0,10000); editor->installEventFilter(const_cast(this)); return editor;},,,8.4 代理(Delegate),setEditorData()函數(shù)的具體實(shí)現(xiàn)代碼如下:void SpinDelegate::setEditorData(QWidget *editor,const QModelIndex &index) cons

67、t{ int value =index.model()->data(index).toInt(); QSpinBox *box = static_cast(editor); box->setValue(value);}setModelData()函數(shù)的具體實(shí)現(xiàn)代碼如下:void SpinDelegate::setModelData(QWidget *editor, QAbstractItemM

68、odel *model,const QModelIndex &index) const{ QSpinBox *box = static_cast(editor); int value = box->value(); model->setData(index,value);},,8.4 代理(Delegate),updateEditorGeometry()函數(shù)的具體實(shí)現(xiàn)代碼如下:void

69、 SpinDelegate::updateEditorGeometry(QWidget *editor,const QStyleOptionViewItem &option, const QModelIndex &/*index*/) const{ editor->setGeometry(option.rect);},,,8.4 代理(Delegate),(3)在“main.cpp”文件中添加代碼如

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論