Qt Model View 學習筆記.doc_第1頁
Qt Model View 學習筆記.doc_第2頁
Qt Model View 學習筆記.doc_第3頁
Qt Model View 學習筆記.doc_第4頁
Qt Model View 學習筆記.doc_第5頁
已閱讀5頁,還剩25頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

Qt Model/View 學習筆記/main-snapshot/model-view-programming.html介紹Qt 4推出了一組新的item view類,它們使用model/view結構來管理數據與表示層的關系。這種結構帶來的功能上的分離給了開發(fā)人員更大的彈性來定制數據項的表示,它也提供一個標準的model接口,使得更多的數據源可以被這些item view使用。這里對model/view的結構進行了描述,結構中的每個組件都進行了解釋,給出了一些例子說明了提供的這些類如何使用。Model/View 結構Model-View-Controller(MVC), 是從Smalltalk發(fā)展而來的一種設計模式,常被用于構建用戶界面。經典設計模式的著作中有這樣的描述:MVC 由三種對象組成。Model是應用程序對象,View是它的屏幕表示,Controller定義了用戶界面如何對用戶輸入進行響應。在MVC之前,用戶界面設計傾向于三者揉合在一起,MVC對它們進行了解耦,提高了靈活性與重用性。假如把view與controller結合在一起,結果就是model/view結構。這個結構依然是把數據存儲與數據表示進行了分離,它與MVC都基于同樣的思想,但它更簡單一些。這種分離使得在幾個不同的view上顯示同一個數據成為可能,也可以重新實現新的view,而不必改變底層的數據結構。為了更靈活的對用戶輸入進行處理,引入了delegate這個概念。它的好處是,數據項的渲染與編程可以進行定制。如上圖所示,model與數據源通訊,并提供接口給結構中的別的組件使用。通訊的性質依賴于數據源的種類與model實現的方式。view從model獲取model indexes,后者是數據項的引用。通過把model indexes提供給model,view可以從數據源中獲取數據。在標準的views中,delegate會對數據項進行渲染,當某個數據項被選中時,delegate通過model indexes與model直接進行交流??偟膩碚f,model/view 相關類可以被分成上面所提到的三組:models,views,delegates。這些組件通過抽象類來定義,它們提供了共同的接口,在某些情況下,還提供了缺省的實現。抽象類意味著需要子類化以提供完整的其他組件希望的功能。這也允許實現定制的組件。models,views,delegates之間通過信號,槽機制來進行通訊:從model發(fā)出的信號通知view數據源中的數據發(fā)生了改變。從view發(fā)出的信號提供了有關被顯示的數據項與用戶交互的信息。從delegate發(fā)生的信號被用于在編輯時通知model和view關于當前編輯器的狀態(tài)信息。Models所有的item models都基于QAbstractItemModel類,這個類定義了用于views和delegates訪問數據的接口。數據本身不必存儲在model,數據可被置于一個數據結構或另外的類,文件,數據庫,或別的程序組件中。關于model的基本概念在Model Classes部分中描述。QAbstractItemModel提供給數據一個接口,它非常靈活,基本滿足views的需要,無論數據用以下任何樣的形式表現,如tables,lists,trees。然而,當你重新實現一個model時,如果它基于table或list形式的數據結構,最好從QAbstractListModel,QAbstractTableModel開始做起,因為它們提供了適當的常規(guī)功能的缺省實現。這些類可以被子類化以支持特殊的定制需求。子類化model的過程在Create New Model部分討論QT提供了一些現成的models用于處理數據項:QStringListModel用于存儲簡單的QString列表。QStandardItemModel管理復雜的樹型結構數據項,每項都可以包含任意數據。QDirModel 提供本地文件系統(tǒng)中的文件與目錄信息。QSqlQueryModel,QSqlTableModel,QSqlRelationTableModel用來訪問數據庫。假如這些標準Model不滿足你的需要,你應該子類化QAbstractItemModel,QAbstractListModel或是QAbstractTableModel來定制。Views不同的view都完整實現了各自的功能:QListView把數據顯示為一個列表,QTableView把Model 中的數據以table的形式表現,QTreeView用具有層次結構的列表來顯示model中的數據。這些類都基于QAbstractItemView抽象基類,盡管這些類都是現成的,完整的進行了實現,但它們都可以用于子類化以便滿足定制需求。DelegatesQAbstractItemDelegate是model/view架構中的用于delegate的抽象基類。缺省的delegate實現在QItemDelegate類中提供。它可以用于Qt標準views的缺省 delegate.排序在model/view架構中,有兩種方法進行排序,選擇哪種方法依賴于你的底層Model。假如你的model是可排序的,也就是它重新實現了QAbstractItemModel:sort()函數,QTableView與QTreeView都提供了API,允許你以編程的方式對Model數據進行排序。另外,你也可以進行交互方式下的排序(例如,允許用戶通過點擊view表頭的方式對數據進行排序),可以這樣做:把QHeaderView:sectionClicked()信號與QTableView:sortByColum()槽或QTreeView:sortByColumn()槽進行聯(lián)結就好了。另一種方法是,假如你的model沒有提供需要的接口或是你想用list view表示數據,可以用一個代理model在用view表示數據之前對你的model數據結構進行轉換。便利類許多便利類都源于標準的view類,它們方便了那些使用Qt中基于項的view與table類,它們不應該被子類化,它們只是為Qt 3的等價類提供一個熟悉的接口。這些類有QListWidget,QTreeWidget,QTableWidget,它們提供了如Qt 3中的QListBox, QlistView,QTable相似的行為。這些類比View類缺少靈活性,不能用于任意的models,推介使用model/view的方法處理數據。介紹Qt提供了兩個標準的models:QStandardItemModel和QDirModel。QStandardItemModel是一個多用途的model,可用于表示list,table,tree views所需要的各種不同的數據結構。這個model也持有數據。QDirModel維護相關的目錄內容的信息,它本身不持有數據,僅是對本地文件系統(tǒng)中的文件與目錄的描述。QDirModel是一個現成的model,很容易進行配置以用于現存的數據,使用這個model,可以很好地展示如何給一個現成的view設定model,研究如何用model indexes來操縱數據。model與views的搭配使用QListView與QTreeView很適合與QDirModel搭配。下面的例子在tree view與list view顯示了相同的信息,QDirModel提供了目錄內容數據。這兩個Views共享用戶選擇,因此每個被選擇的項在每個view中都會被高亮。先裝配出一個QDirModel以供使用,再創(chuàng)建views去顯示目錄的內容。這給我展示了使用model的最簡單的方式。model的創(chuàng)建與使用都在main()函數中完成:int main(int argc, char *argv)QApplicationapp(argc, argv);QSplitter*splitter = newQSplitter;QDirModel*model = newQDirModel;/從缺省目錄創(chuàng)建數據QTreeView*tree = newQTreeView(splitter); tree-setModel(model); tree-setRootIndex(model-index(QDir:currentPath();QListView*list = newQListView(splitter); list-setModel(model); list-setRootIndex(model-index(QDir:currentPath();/配置一個view去顯示model中的數據,只需要簡單地調用setModel(),并把目錄model作為參數傳遞 /setRootIndex()告訴views顯示哪個目錄的信息,這需要提供一個model index,然后用這個 /model index去model中去獲取數據 /index()這個函數是QDirModel特有的,通過把一個目錄做為參數,得到了需要的model index /其他的代碼只是窗口show出來,進入程序的事件循環(huán)就好了splitter-setWindowTitle(Two views onto the same directory model); splitter-show(); return app.exec();上面的例子并沒有展示如何處理數據項的選擇,這包括很多細節(jié),以后會提到。Model類基本概念在model/view構架中,model為view和delegates使用數據提供了標準接口。在Qt中,標準接口QAbstractItemModel類中被定義。不管數據在底層以何種數據結構存儲,QAabstractItemModel的子類會以層次結構的形式來表示數據,結構中包含了數據項表。我們按這種約定來訪問model中的數據項,但這個約定不會對如何顯示這些數據有任何限制。數據發(fā)生改變時,model通過信號槽機制來通知關聯(lián)的views。Model Indexes為了使數據存儲與數據訪問分開,引入了model index的概念。通過model index,可以引用model中的數據項,Views和delegates都使用indexes來訪問數據項,然后再顯示出來。因此,只有model需要了解如何獲取數據,被model管理的數據類型可以非常廣泛地被定義。Model indexes包含一個指向創(chuàng)建它們的model的指針,這會在配合多個model工作時避免混亂。QAbstractItemModel*model = index.model();model indexes提供了對一項數據信息的臨時引用,通過它可以訪問或是修改model中的數據。既然model有時會重新組織內部的數據結構,這時model indexes便會失效,因此不應該保存臨時的model indexes。假如需要一個對數據信息的長期的引用,那么應該創(chuàng)建一個persistentmodel index。這個引用會保持更新。臨時的model indexes由QModelIndex提供,而具有持久能力的model indexes則由QPersistentModelIndex提供。在獲取對應一個數據項的model index時,需要考慮有關于model的三個屬性:行數,列數,父項的model index。行與列在最基本的形式中,一個model可作為一個簡單的表來訪問,每個數據項由行,列數來定位。這必不意味著底層的數據用數組結構來存儲。行和列的使用僅僅是一種約定,它允許組件之間相互通訊??梢酝ㄟ^指定model中的行列數來獲取任一項數據,可以得到與數據項一一對應的那個index。QModelIndexindex = model-index(row, column, .);Model為簡單的,單級的數據結構如list與tables提供了接口,它們如上面代碼所顯示的那樣,不再需要別的信息被提供。當我們在獲取一個model index時,我們需要提供另外的信息。上圖代表一個基本的table model,它的每一項用一對行列數來定位。通過行列數,可以獲取代表一個數據項的model index .QModelIndexindexA = model-index(0, 0,QModelIndex();QModelIndexindexB = model-index(1, 1,QModelIndex();QModelIndexindexC = model-index(2, 1,QModelIndex();一個model的頂級項,由QModelIndex()取得,它們上式被用作父項。父項類似于表的接口在搭配使用table或list view時理想的,這種行列系統(tǒng)與view顯示的方式是確切匹配的。然則,像tree views這種結構需要model提供更為靈活的接口來訪問數據項。每個數據項可能是別的項的父項,上級的項可以獲取下級項的列表。當獲取model中數據項的index時,我們必須指定關于數據項的父項的信息。在model外部,引用一個數據項的唯一方法就是通過model index,因此需要在求取model index時指定父項的信息。QModelIndexindex = model-index(row, column, parent);上圖中,A項和C項作為model中頂層的兄弟項:QModelIndexindexA = model-index(0, 0, QModelIndex();QModelIndexindexC = model-index(2, 1, QModelIndex();A有許多孩子,它的一個孩子B用以下代碼獲?。篞ModelIndexindexB = model-index(1, 0, indexA);項角色model中的項可以作為各種角色來使用,這允許為不同的環(huán)境提供不同的數據。舉例來說,Qt:DisplayRole被用于訪問一個字符串,它作為文本會在view中顯示。典型地,每個數據項都可以為許多不同的角色提供數據,標準的角色在Qt:ItemDataRole中定義。我們可以通過指定model index與角色來獲取我們需要的數據:QVariantvalue = model-data(index, role);角色指出了從model中引用哪種類型的數據。views可以用不同的形式顯示角色,因此為每個角色提供正確的信息是非常重要的。通過為每個角色提供適當數據,model也為views和delegates提供了暗示,如何正確地把這些數據項顯給用戶。不同的views可以自由地解析或忽略這些數據信息,對于特殊的場合,也可以定義一些附加的角色。概念總結:1,Model indexes為views與delegages提供model中數據項定位的信息,它與底層的數據結構無關。2,通過指定行,列數,父項的model index來引用數據項。3,依照別的組件的要求,model indexes被model構建。4,使用index()時,如果指定了有效的父項的model index,那么返回得到的model index對應于父項的某個孩子。5,使用index()時,如果指定了無效的父項的model index,那么返回得到的model index對應于頂層項的某個孩子。6, 角色對一個數據項包含的不同類型的數據給出了區(qū)分。使用Model IndexesQDirModel*model = newQDirModel;QModelIndexparentIndex = model-index(QDir:currentPath(); int numRows = model-rowCount(parentIndex);for (int row = 0; row index(row, 0, parentIndex); tring text = model-data(index, Qt:DisplayRole).toString(); / Display the text in a widget. 以上的例子說明了從model中獲取數據的基本原則:1,model的尺寸可以從rowCount()與columnCount()中得出。這些函數通常都需要一個表示父項的model index。2,model indexes用來從model中訪問數據項,數據項用行,列,父項model index定位。3, 為了訪問model頂層項,可以使用QModelIndex()指定。4, 數據項為不同的角色提供不同的數據。為了獲取數據,除了model index之外,還要指定角色。創(chuàng)建新的Models介紹model/view組件之間功能的分離,允許創(chuàng)建model利用現成的views。這也可以使用標準的功能 圖形用戶接口組件像QListView,QTableView和QTreeView來顯示來自各種數據源的數據為。QAbstractListModel類提供了非常靈活的接口,允許數據源以層次結構的形式來管理信息,也允許以某種方式對數據進行插入、刪除、修改和存儲。它也提供了對拖拽操作的支持。QAbstractListModel與QAbstractTableModel為簡單的非層次結構的數據提供了接口,對于比較簡單的list和table models來說,這是不錯的一個開始點。設計一個Model當我們?yōu)榇嬖诘臄祿Y構新建一個model時,首先要考慮的問題是應該選用哪種model來為這些數據提供接口。假如數據結構可以用數據項的列表或表來表示,那么可以考慮子類化QAbstractListModel或QAbstractTableModel,既然這些類已經合理地對許多功能提供缺省實現。然而,假如底層的數據結構只能表示成具有層次結構的樹型結構,那么必須得子類化QAbstractItemModel。無論底層的數據結構采取何種形式,在特定的model中實現標準的QAbstractItemModelAPI總是一個不錯的主意,這使得可以使用更自然的方式對底層的數據結構進行訪問。這也使得用數據構建model 更為容易,其他的model/view組件也可以使用標準的API與之進行交互。一個只讀model示例這個示例實現了一個簡單的,非層次結構的,只讀的數據model,它基于QStringistModel類。它有一個QStringList作為它內部的數據源,只實現了一些必要的接口。為了簡單化,它子類化了QAbstractListModel,這個基類提供了合理的缺省行為,對外提供了比QAbstractItemModel更為簡單的接口。當我們實現一個model時,不要忘了QAbstractItemModel本身不存儲任何數據,它僅僅提供了給views訪問數據的接口。classStringListModel: publicQAbstractListModel Q_OBJECTpublic:StringListModel(const QStringList &strings, QObject *parent = 0) :QAbstractListModel(parent), stringList(strings) introwCount(const QModelIndex &parent = QModelIndex() const; QVariantdata(const QModelIndex &index, int role) const; QVariantheaderData(int section, Qt:Orientation orientation, int role = Qt:DisplayRole) const;private:QStringListstringList;除了構造函數,我們僅需要實現兩個函數:rowCount()返回model中的行數,data()返回與特定model index對應的數據項。具有良好行為的model也會實現headerData(),它返回tree和table views需要的,在標題中顯示的數據。因為這是一個非層次結構的model,我們不必考慮父子關系。假如model具有層次結構,我們也應該實現index()與parent()函數。Model的尺寸我們認為model中的行數與string list中的string數目一致:intStringListModel:rowCount(const QModelIndex &parent) const return stringList.count();在缺省情況下,從QAbstractListModel派生的model只具有一列,因此不需要實現columnCount()。Model 標題與數據QVariantStringListModel:data(const QModelIndex &index, int role) const if (!index.isValid() return QVariant(); if (index.row() = stringList.size() return QVariant(); if (role = Qt:DisplayRole) return stringList.at(index.row(); else return QVariant();QVariantStringListModel:headerData(int section, Qt:Orientation orientation, int role) const if (role != Qt:DisplayRole) return QVariant(); if (orientation = Qt:Horizontal) return QString(Column %1).arg(section); else return QString(Row %1).arg(section);一個數據項可能有多個角色,根據角色的不同輸出不同的數據。上例中,model中的數據項只有一個角色 ,DisplayRole,然而我們也可以重用提供給DisplayRole的數據,作為別的角色使用,如我們可以作為ToolTipRole來用。可編輯的model上面我們演示了一個只讀的model,它只用于向用戶顯示,對于許多程序來說,可編輯的list model可能更有用。我們只需要給只讀的model提供另外兩個函數flags()與setData()的實現。下列函數聲明被添加到類定義中: Qt:ItemFlagsflags(const QModelIndex &index) const; boolsetData(const QModelIndex &index, const QVariant &value, int role = Qt:EditRole);讓model可編輯delegate會在創(chuàng)建編輯器之前檢查數據項是否是可編輯的。model必須得讓delegate知道它的數據項是可編輯的。這可以通過為每一個數據項返回一個正確的標記得到,在本例中,我們假設所有的數據項都是可編輯可選擇的:Qt:ItemFlagsStringListModel:flags(const QModelIndex &index) const if (!index.isValid() return Qt:ItemIsEnabled; returnQAbstractItemModel:flags(index) | Qt:ItemIsEditable;我們不必知道delegate執(zhí)行怎樣實際的編輯處理過程,我們只需提供給delegate一個方法,delegate會使用它對model中的數據進行設置。這個特殊的函數就是setData():boolStringListModel:setData(const QModelIndex &index, const QVariant &value, int role) if (index.isValid() & role = Qt:EditRole) stringList.replace(index.row(), value.toString();emitdataChanged(index, index); return true; return false;當數據被設置后,model必須得讓views知道一些數據發(fā)生了變化,這可通過發(fā)射一個dataChanged() 信號實現。因為只有一個數據項發(fā)生了變化,因此在信號中說明的變化范圍只限于一個model index。插入,刪除行在model中改變行數與列數是可能的。當然在本列中,只考慮行的情況,我們只需要重新實現插入、刪除的函數就可以了,下面應在類定義中聲明: boolinsertRows(int position, int rows, const QModelIndex &index = QModelIndex(); boolremoveRows(int position, int rows, const QModelIndex &index = QModelIndex();既然model中的每行對應于列表中的一個string,因此,insertRows()函數在string list 中指定位置插入一個空string,父index通常用于決定model中行列的位置,本例中只有一個單獨的頂級項,困此只需要在list中插入空string。boolStringListModel:insertRows(int position, int rows, const QModelIndex &parent)beginInsertRows(QModelIndex(), position, position+rows-1); for (int row = 0; row rows; +row) stringList.insert(position, ); endInsertRows(); return true;beginInsertRows()通知其他組件行數將會改變。endInsertRows()對操作進行確認與通知。返回true表示成功。刪除操作與插入操作類似:boolStringListModel:removeRows(int position, int rows, const QModelIndex &parent)beginRemoveRows(QModelIndex(), position, position+rows-1); for (int row = 0; row rows; +row) stringList.removeAt(position); endRemoveRows(); return true;View 類概念在model/view架構中,view從model中獲得數據項然后顯示給用戶。數據顯示的方式不必與model提供的表示方式相同,可以與底層存儲數據項的數據結構完全不同。內容與顯式的分離是通過由QAbstractItemModel提供的標準模型接口,由QAsbstractItemview提供的標準視圖接口共同實現的。普遍使用model index來表示數據項。view負責管理從model中讀取的數據的外觀布局。它們自己可以去渲染每個數據項,也可以利用delegate來既處理渲染又進行編輯。除了顯示數據,views也處理數據項的導航,參與有關于數據項選擇的部分功能。view也實現一些基本的用戶接口特性,如上下文菜單與拖拽功能。view也為數據項提供了缺省的編程功能,也可搭配delegate實現更為特殊的定制編輯的需求。一個view創(chuàng)建時必不需要model,但在它能顯示一些真正有用的信息之前,必須提供一個model。view通過使用selections來跟蹤用戶選擇的數據項。每個view可以維護單獨使用的selections,也可以在多個views之間共享。有些views,如QTableView和QTreeView,除數據項之外也可顯示標題(Headers),標題部分通過一個view來實現,QHeaderView。標題與view一樣總是從相同的model中獲取數據。從 model中獲取數據的函數是QabstractItemModel:headerDate(),一般總是以表單的形式中顯示標題信息??梢詮腝HeaderView子類化,以實現更為復雜的定制化需求。使用現成的viewQt提供了三個現成的view 類,它們能夠以用戶熟悉的方式顯示model中的數據。QListView把model中的數據項以一個簡單的列表的形式顯示,或是以經典的圖標視圖的形式顯示。QTreeView把model中的數據項作為具有層次結構的列表的形式顯示,它允許以緊湊的深度嵌套的結構進行顯示。QTableView卻是把model中的數據項以表格的形式展現,更像是一個電子表格應用程序的外觀布局。以上這些標準view的行為足以應付大多數的應用程序,它們也提供了一些基本的編輯功能,也可以定制特殊的需求。使用model以前的例子中創(chuàng)建過一個string list model,可以給它設置一些數據,再創(chuàng)建一個view把model中的內容展示出來:int main(int argc, char *argv)QApplicationapp(argc, argv);/ Unindented for quoting purposes:QStringListnumbers;numbers One Two Three Four setModel(model); view-show(); return app.exec();view會渲染model中的內容,通過model的接口來訪問它的數據。當用戶試圖編輯數據項時,view會使用缺省的delegate來提供一個編輯構件。一個model,多個views為多個views提供相同的model是非常簡單的事情,只要為每個view設置相同的model。QTableView*firstTableView = new QTableView;QTableView*secondTableView = new QTableView; firstTableView-setModel(model); secondTableView-setModel(model);在model/view架構中信號、槽機制的使用意味著model中發(fā)生的改變會傳遞中聯(lián)結的所有view中,這保證了不管我們使用哪個view,訪問的都是同樣的一份數據。上面的圖展示了一個model上的兩個不同的views,盡管在不同的view中顯示的model中的數據是一致的,每個view都維護它們自己的內部選擇模型,但有時候在某些情況下,共享一個選擇模型也是合理的。處理數據項的選擇view中數據項選擇機制由QItemSelectionModel類提供。所有標準的view缺省都構建它們自己的選擇模型,以標準的方式與它們交互。選擇模型可以用selectionModel()函數取得,替代的選擇模型也可以通過setSelectionModel()來設置。當我們想在一個model上提供多個一致的views時,這種對選擇模型的控制能力非常有用。通常來講,除非你子類化一個model或view,你不必直接操縱selections的內容。多個views之間共享選擇接著上邊的例子,我們可以這樣:secondTableView-setSelectionModel(firstTableView-selectionModel();現在所有views都在同樣的選擇模型上操作,數據與選擇項都保持同步。上面的例子中,兩個view的類型是相同的,假如這兩個view類型不同,那么所選擇的數據項在每個view中的表現形式會有很大的不同。例如,在一個table view中一個連續(xù)的選擇,在一個tree view中表現出來的可能會是幾個高亮的數據項片斷的組合。在views中選擇數據項概念用于新的view類中的選擇模型比Qt3中的模型有了很大的改進。它為基于model/view架構的選擇提供了更為全面的描述。盡管對提供了的views來說,負責操縱選擇的標準類已經足以應付,但是你也可以創(chuàng)建特定的選擇模型來滿足你特殊的需求。關于在view被選擇的數據項的信息保持在QItemSelectionModel類的實例中。它也為每個獨立的model中的數據項維護model indexes信息,與任何views都關聯(lián)關系。既然一個model可用于多個views,那么在多個views之間共享選擇信息也是可以做到的,這使得多個views可以以一致的方式進行顯示。選擇由多個選擇范圍組成。通過僅僅記錄開始model indexes與結束model indexes,最大化地記錄了可以選擇的范圍。非連續(xù)選擇數據項由多個選擇范圍來描述。選擇模型記錄model indexes的集合來描述一個選擇。最近選擇的數據項被稱為currentselection。應用程序可以通過使用某種類型的選擇命令來修改選擇的效果。在進行選擇操作時,可以把QItemSelectionModel看成是model中所有數據項選擇狀態(tài)的一個記錄。一旦建立一個選擇模型,所有項的集合都可以選擇,撤消選擇,或者選擇狀態(tài)進行切換而不需要知道哪個數據項是否已經被選擇過。所有被選擇的項的indexes在任何時候都可以得到,通過信號槽機制可以通知別的組件發(fā)生的變化。使用選擇模型標準view類提供了缺省的選擇模型,它們可以在大次數程序中使用。一個view中的選擇模型可以通過調用view的函數selectionModel()取得,也可以通過setSelectionModel()在多個views之間共享選擇模型,因此總的來說構建一個新的模型一般情況不太必要。通過給QItemSelection指定一個model,一對model indexes,可以創(chuàng)建一個選擇。indexes的用法依賴于給定的model,這兩個indexes被解釋成選擇的區(qū)塊中的左上角項和右下角項。model中的項的選擇服從于選擇模型。選擇項構建一個table model ,它有32個項,用一個table view進行顯示:TableModel*model = new TableModel(8, 4, &app);QTableView*table = new QTableView(0); table-setModel(model);QItemSelectionModel*selectionModel = table-selectionModel();QModelIndextopLeft;QModelIndexbottomRight; topLeft = model-index(0, 0, QModelIndex(); bottomRight = model-index(5, 2, QModelIndex();QItemSelectionselection(topLeft, bottomRight); selectionModel-select(selection, QItemSelectionModel:Select);結果如下:讀取選擇狀態(tài)存儲在選擇模型中indexes可以用selectionIndexes()函數來讀取。它返回一個未排序的model indexes列表,我們可以遍歷它,如果我們知道他們關聯(lián)于哪個model的話。QModelIndexListindexes = selectionModel-selectedIndexes();QModelIndexindex;foreach(index, indexes) QString text = QString(%1,%2).arg(index.row().arg(index.column(); model-setData(index, text); 選擇模型在選擇發(fā)生變化時會發(fā)出信號。這用于通知別的組件包括整體與當前焦點項所發(fā)生的變化。我們可以連接selectionChanged()信號到一個槽,檢查當信號產生時哪些項被選擇或被取消選擇。這個槽被調用時帶有兩個參數,它們都是QItemSelection對象,一個包含新被選擇的項,另一個包含新近被取消選擇的項。下面的代碼演示了給新選擇的項添加數據內容,新近被取消選擇的項的內容被清空。void MainWindow:updateSelection(constQItemSelection&selected, constQItemSelection&deselected)QModelIndexindex;QModelIndexListitems = selected.indexes();foreach(index, items) QString text = QString(%1,%2).arg(index.row().arg(index.column(); model-setData(index, text); items = deselected.indexes();foreach(index, items) model-setData(index, );也可以通過響應currentChanged()信號來跟蹤當前焦點項.對應的槽就有兩個接收參數,一個表示之前的焦點,另一個表示當前的焦點。void MainWindow:changeCurrent(constQModelIndex¤t, constQModelIndex&previous) statusBar()-showMessage( tr(Moved from (%1,%2) to (%3,%4) .arg(previous.row().arg(previous.column() .arg(current.row().arg(current.column();更新選擇選擇指令是通過選擇標志提供的,它被定義在QItemSelectionModel:SelectionFlag中。常用的有Select標記,Toggle標記,Deselect標記,Current標記,

溫馨提示

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

最新文檔

評論

0/150

提交評論