




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第8章 Qt 5模型/視圖結構概述概述8.18.2模型(模型(Model)視圖(視圖(View)8.38.4代理(代理(Delegate)Qt的模型/視圖結構分為三部分:模型(Model)、視圖(View)和代理(Delegate)。其中,模型與數據源通信,并為其他部件提供接口;而視圖從模型中獲得用來引用數據條目的模型索引(Model Index)。在視圖中,代理負責繪制數據條目,當編輯條目時,代理和模型直接進行通信。模型/視圖/代理之間通過信號和槽進行通信,如圖8.1所示。8.1 概述概述8.1.1 基本概念基本概念1模型(模型(Model)InterView框架中的所有模型都基于抽象基類Q
2、AbstractItemModel類,此類由QProxyModel、QAbstractListModel、QAbstractTableModel、QAbstractProxyModel、QDirModel、QFileSystemModel、QHelpContentModel 和 QStandardItemModel類繼承。其中,QAbstractListModel類和QAbstractTableModel類是列表和表格模型的抽象基類,如果需要實現列表或表格模型,則應從這兩個類繼承。8.1.1 基本概念基本概念2視圖(視圖(View)InterView框架中的所有視圖都基于抽象基類QAbstra
3、ctItemView類,此類由QColumnView、QHeaderView、QListView、QTableView和QTreeView類繼承。其中,QListView類由QUndoView類和QListWidget類繼承;QTableView類由QTableWidget類繼承;QTreeView類由QTreeWidget類繼承。而QListWidget類、QTableWidget類和QTreeWidget類實際上已經包含了數據,是模型/視圖集成在一起的類。3代理(代理(Delegate)InterView框架中的所有代理都基于抽象基類QAbstractItemDelegate類,此類由QI
4、temDelegate 和 QStyledItemDelegate類繼承。其中,QItemDelegate類由表示數據庫中關系代理的QSqlRelationalDelegate類繼承。8.1.2 【實例】:模型【實例】:模型/視圖類使用視圖類使用【例】(簡單) 實現一個簡單的文件目錄瀏覽器,完成效果如圖8.2所示。實例文件見光盤CH801。創(chuàng)建工程“DirModeE”,其源文件“main.cpp”中的具體代碼。最后運行結果如圖8.2所示。8.2 模型(模型(Model)【例】(難度一般) 通過實現將數值代碼轉換為文字的模型來介紹如何使用自定義模型。此模型中保存了不同軍種的各種武器,實
5、現效果如圖8.3所示。實例文件見光盤CH802。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)
6、tr(M1A1)tr(F-22);8.2 模型(模型(Model)columnCount()函數中,模型的列固定為“3”,所以直接返回“3”。int ModelEx:columnCount(const QModelIndex &parent) const return 3; rowCount()函數返回模型的行數。int ModelEx:rowCount(const QModelIndex &parent) const return army.size();data()函數返回指定索引的數據,即將數值映射為文字。8.2 模型(模型(Model)表8.1列出了Item主要的角色及
7、其描述。常 量描 述Qt:DisplayRole顯示文字Qt:DecorationRole繪制裝飾數據(通常是圖標)Qt:EditRole在編輯器中編輯的數據Qt:ToolTipRole工具提示Qt:StatusTipRole狀態(tài)欄提示Qt:WhatsThisRoleWhats This文字Qt:SizeHintRole尺寸提示Qt:FontRole默認代理的繪制使用的字體Qt:TextAlignmentRole默認代理的對齊方式Qt:BackgroundRole默認代理的背景畫刷Qt:ForegroundRole默認代理的前景畫刷Qt:CheckStateRole默認代理的檢查框狀態(tài)Qt:U
8、serRole用戶自定義的數據的起始位置8.2 模型(模型(Model)headerData()函數返回固定的表頭數據,設置水平表頭的標題,具體代碼如下:QVariant ModelEx:headerData(int section, Qt:Orientation orientation, int role) const if(role=Qt:DisplayRole&orientation=Qt:Horizontal) return headersection; return QAbstractTableModel:headerData(section,orientation,role
9、);8.2 模型(模型(Model)(3)在源文件“main.cpp”中,將模型和視圖關聯,具體代碼如下:#include #include modelex.h#include 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(); return a.exec()
10、;(4)運行結果如圖8.3所示。8.3 視圖(視圖(View)【例】(難度中等) 通過利用自定義的View,實現一個對TableModel的表格數據進行顯示的柱狀統(tǒng)計圖例子,以此介紹如何應用自定義的View。實現效果如圖8.4所示。實例文件見光盤CH803。8.3 視圖(視圖(View)具體實現步驟如下。(1)完成主窗體,以便顯示View的內容。MainWindow 類繼承自QMainWindow類,作為主窗體。以下是頭文件“mainwindow.h”的具體代碼。(2)下面是源文件“mainwindow.cpp”中的具體代碼。setupModel()函數新建一個Model,并設置表頭數據,其具
11、體實現代碼如下: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(退休);8.3 視圖(視圖(View)setupView()函數的具體實現代碼如下:void MainW
12、indow: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),tab
13、le,SLOT(selectionChanged(QItemSelection,QItemSelec-tion);/(b) splitter = new QSplitter; splitter-setOrientation(Qt:Vertical); splitter-addWidget(table); setCentralWidget(splitter);8.3 視圖(視圖(View)(3)此時,運行效果如圖8.5所示。8.3 視圖(視圖(View)(1)在頭文件“mainwindow.h”中添加代碼如下:public: void openFile(QString);public slots
14、: void slotOpen();(2)在源文件mainwindow.cpp中添加代碼如下:#include #include #include #include 其中,其中,在createAction()函數中添加代碼如下:connect(openAct,SIGNAL(triggered(),this,SLOT(slotOpen();8.3 視圖(視圖(View)槽函數slotOpen()完成打開標準文件對話框,具體代碼如下:void MainWindow:slotOpen() QString name; name = QFileDialog:getOpenFileName(this,打開
15、,.,histogram files (*.txt); if (!name.isEmpty() openFile(name);openFile()函數完成打開所選的文件內容,其具體實現代碼。8.3 視圖(視圖(View)新建一個文本文件,命名為“histogram.txt”,保存在項目D:QtCH8CH803 build-ViewEx-Desktop_Qt_5_4_0_MinGW_32bit-Debug目錄下,文件內容及打開后的效果如圖8.6所示。8.3 視圖(視圖(View)以上完成了表格數據的加載,下面介紹柱狀統(tǒng)計圖的繪制。具體實現步驟如下。(1)自定義HistogramView類繼承自Q
16、AbstractItemView類,用于對表格數據進行柱狀圖顯示。下面是頭文件“histogramview.h”的具體代碼。(2)源文件“histogramview.cpp”的具體代碼。dataChanged()函數實現當Model中的數據更改時,調用繪圖設備的update()函數進行更新,反映數據的變化。具體實現代碼。void HistogramView:dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) QAbstractItemView:dataChanged(topLeft,bo
17、ttomRight); viewport()-update();setSelectionModel()函數為selections賦初值,具體代碼如下:void HistogramView:setSelectionModel(QItemSelectionModel *selectionModel) selections=selectionModel;8.3 視圖(視圖(View)(3)下面的工作就是完成對選擇項的更新。selectionChanged()函數中完成當數據項發(fā)生變化時調用update()函數,重繪繪圖設備即可工作。此函數是將其他View中的操作引起的數據項選擇變化反映到自身View
18、的顯示中。具體代碼如下:void HistogramView:selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) viewport()-update();鼠標按下事件函數mousePressEvent(),在調用setSelection()函數時確定鼠標單擊點是否在某個數據項的區(qū)域內,并設置選擇項。具體代碼如下:void HistogramView:mousePressEvent(QMouseEvent *event) QAbstractItemView:mouse
19、PressEvent(event); setSelection(QRect(event-pos().x(),event-pos().y(),1,1),QItemSelec tionModel:SelectCurrent);8.3 視圖(視圖(View)setSelection()函數的具體代碼如下:void HistogramView:setSelection(const QRect &rect,QItemSelectionModel:SelectionFlags flags) int rows = model()-rowCount(rootIndex();/獲取總行數 int col
20、umns = 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 (!ersected(rect).isEmpty() selectedIndex = index; if(selectedIndex.isValid()/(d)
21、selections-select(selectedIndex,flags); else QModelIndex noIndex; selections-select(noIndex,flags); 8.3 視圖(視圖(View)indexAt()函數的具體內容。由于本例未用到以下函數的功能,所以沒有實現具體內容,但仍然要寫出函數體的框架,代碼如下:QRect HistogramView:visualRect(const QModelIndex &index)constvoid HistogramView:scrollTo(const QModelIndex &index,Sc
22、rollHint)QModelIndex HistogramView:moveCursor(QAbstractItemView:CursorAction cursor Action, Qt:KeyboardModifiers modifiers)int HistogramView:horizontalOffset()constint HistogramView:verticalOffset()constbool HistogramView:isIndexHidden(const QModelIndex &index)constQRegion HistogramView:visualRe
23、gionForSelection(const QItemSelection & selection)const8.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()
24、 = 3)/退休 region = SRegionListindex.row(); return region;8.3 視圖(視圖(View)(4)在頭文件“mainwindow.h”中添加代碼如下:#include histogramview.hprivate: HistogramView *histogram;(5)在源文件“mainwindow.cpp”中添加代碼,其中,setupView()函數的代碼修改。(6)運行結果如圖8.4所示。8.4 代理(代理(Delegate)【例】(難度中等) 利用Delegate設計表格中控件如圖8.7所示。實例文件見光盤CH804。8.4 代理(代理
25、(Delegate)具體實現步驟如下。(1)首先,加載表格數據,以便后面的操作。源文件“main.cpp”中的具體代碼如下:(2)選擇“構建”“構建項目DateDelegate”菜單項,首先按照如圖8.8所示的格式編輯本例所用的數據文件“test.txt”,保存在項目D:QtCH8CH804 build- DateDelegate-Desktop_Qt_5_4_0_MinGW_32bit- Debug目錄下,然后運行程序,結果如圖8.7所示。8.4 代理(代理(Delegate)(3)在圖8.7中,使用手動的方式實現對生日的錄入編輯。下面使用日歷編輯框QDateTimeEdit 控件實現對生日
26、的編輯,用自定義的Delegate來實現。(4)DateDelegate 繼承自QItemDelegate類。頭文件“datedelegate.h”中的具體代碼如下:#include class DateDelegate : public QItemDelegate Q_OBJECTpublic: DateDelegate(QObject *parent = 0); QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem & option, const QModelIndex &index) const
27、;/(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 QM
28、odelIndex &index) const;/更新控件區(qū)的顯示;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 &/*
29、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;8.4 代理(代理(Delegate)setEditorData()函數的具體代碼如下:void DateDeleg
30、ate: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);/設置控件的顯示數據8.4 代理(代理(Delegate)setModelData()函數的具體代碼如
31、下: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:upda
32、teEditorGeometry(QWidget *editor,const QStyle OptionViewItem &option,const QModelIndex &index) const editor-setGeometry(option.rect);8.4 代理(代理(Delegate)(6)在“main.cpp”文件中添加如下代碼:#include datedelegate.h在語句tableView.setModel(&model);后面添加如下代碼:DateDelegate dateDelegate;tableView.setItemDelegat
33、eForColumn(1,&dateDelegate);(7)此時運行程序,雙擊第1行第2列,將顯示如圖8.9所示的日歷編輯框控件。8.4 代理(代理(Delegate)下面使用下拉列表框QComboBox控件實現對職業(yè)類型的輸入編輯,使用自定義的Delegate實現。(1)ComboDelegate繼承自QItemDelegate類。頭文件“combodelegate.h”中的具體代碼如下:#include class ComboDelegate : public QItemDelegate Q_OBJECTpublic: ComboDelegate(QObject *parent
34、= 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 up
35、dateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;8.4 代理(代理(Delegate)(2)源文件“combodelegate.cpp”中的具體代碼如下:#include combodelegate.h#include ComboDelegate:ComboDelegate(QObject *parent) : QItemDelegate(parent)8.4 代理(代理(Delegate)createEditor()函
36、數中創(chuàng)建了一個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(醫(yī)生); editor-addItem(律師
37、); editor-addItem(軍人); editor-installEventFilter(const_cast(this); return editor;8.4 代理(代理(Delegate)setEditorData()函數中更新了Delegate控件中的數據顯示,具體代碼如下:void ComboDelegate:setEditorData(QWidget *editor,const QModelIndex &index) const QString str =index.model()-data(index).toString(); QComboBox *box = st
38、atic_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
39、(index,str);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(&a
40、mp;model)的后面添加以下代碼:ComboDelegate comboDelegate;tableView.setItemDelegateForColumn(2,&comboDelegate);8.4 代理(代理(Delegate)此時運行程序,雙擊第1行第3列,顯示如圖8.10所示的下拉列表。8.4 代理(代理(Delegate)下面使用QSpinBox控件實現對收入的輸入編輯,調用自定義的Delegate來實現。SpinDelegate類的實現與ComboDelegate類的實現類似,此處不再詳細講解。(1)頭文件“spindelegate.h”中的具體代碼如下:#inclu
41、de class SpinDelegate : public QItemDelegate Q_OBJECTpublic: 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 &a
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025至2030年中國水洗白鴨毛數據監(jiān)測研究報告
- 2024年南平市建陽區(qū)社會統(tǒng)一教師招聘筆試真題
- 孟津租房合同范本
- 2024年嘉興市消防救援支隊政府專職消防員消防文員招聘考試真題
- 2024年濟寧市市屬事業(yè)單位招聘綜合類崗位考試真題
- 電梯的智能控制與環(huán)保節(jié)能雙贏之道
- 電燈弱電合同范本
- 教材采購合同范本
- 小分子藥物國際合作行業(yè)深度調研及發(fā)展戰(zhàn)略咨詢報告
- 勞務派遣施工合同模板
- 中職高教版(2023)語文職業(yè)模塊-第五單元:走近大國工匠(一)展示國家工程-了解工匠貢獻【課件】
- 物業(yè)管理車輛出入管理制度
- 家庭康復服務的商業(yè)價值與發(fā)展趨勢
- 2025年施工項目部《春節(jié)節(jié)后復工復產》工作實施方案 (3份)-75
- 礦山安全生產工作總結
- 小學教師培訓課件:做有品位的小學數學教師
- U8UAP開發(fā)手冊資料
- 監(jiān)護人考試20241208練習試題附答案
- 證券公司裝修施工合同工程
- 人教版PEP三年級到六年級單詞以及重點句型
- 中建總承包項目高支模專項施工方案含計算書
評論
0/150
提交評論