版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
Ref:/superjoel/article/details/5112120setD^taPBintEvenitcommitDataModelIndex<place”widget|Rowi(CGliumdiel&gat^)ht!p://blog.G5/superjoeliReal'm&at*ofdata(FiEe/Databas^.,JfetchupdatesetD^taPBintEvenitcommitDataModelIndex<place”widget|Rowi(CGliumdiel&gat^)ht!p://blog.G5/superjoeliReal'm&at*ofdata(FiEe/Databas^.,Jfetchupdates&tDatasctDatadata-dataGTiLangeddatarendering|SelectionmodelSelectionmode)Model1McdeEnUser|Painter也色訕i=蒼一般來(lái)說(shuō),Model里面并沒(méi)有真正存儲(chǔ)數(shù)據(jù)(數(shù)據(jù)少的話也可以直接存儲(chǔ)在Model里),它的數(shù)據(jù)是從真正的"肉(raw)"里取得,如一個(gè)diskfile,或database的queryresultset等等。那么這個(gè)model究竟是干什么用的呢?說(shuō)白了吧,它就是負(fù)責(zé)將“肉”數(shù)據(jù)獲取并提供給view,然后將view所做的對(duì)“肉”數(shù)據(jù)的修改更新至真正的"肉"中。所以,讀寫(xiě)文件、操作數(shù)據(jù)庫(kù)、網(wǎng)絡(luò)通訊等一系列與數(shù)據(jù)打交道的工作就在model中做了。有的時(shí)候“肉”可能真的很肥,所以model還有一項(xiàng)重要的工作就是把這些"肉”編號(hào)。這樣就出現(xiàn)了ModelIndex這個(gè)非常重要的類。一般來(lái)說(shuō),它使用一個(gè)2維的編號(hào)(row/colum)來(lái)對(duì)"肉”編號(hào)。但對(duì)于tree這種有層次結(jié)構(gòu)的數(shù)據(jù)來(lái)說(shuō),又加上一個(gè)parentindex作為第3個(gè)編號(hào)。即一個(gè)父親下面的葉子也是從0,0開(kāi)始編號(hào),獲取modelindex的時(shí)候用遞歸來(lái)實(shí)現(xiàn)。0K,現(xiàn)在model已經(jīng)有了一堆編好號(hào)碼的“肉”了,誰(shuí)來(lái)買啊?“肉”便宜了。。。。。。View適時(shí)出現(xiàn),注意,很多view可以同時(shí)來(lái)買同一塊“肉”。(汗,不開(kāi)玩笑了,這篇blog快水了)。當(dāng)view需要顯示某些數(shù)據(jù)時(shí),它們通過(guò)modelindex從model中獲取數(shù)據(jù)(調(diào)用model的data函數(shù),當(dāng)model的data變化時(shí),它也會(huì)自動(dòng)發(fā)dataChangedsignal給所有的view以便它們更新)。當(dāng)然,在view中也可以調(diào)用model的setData函數(shù)來(lái)設(shè)定某個(gè)modelindex所對(duì)應(yīng)的數(shù)據(jù)。這里要說(shuō)明一下model中的數(shù)據(jù),用QVarient來(lái)承載,可以是所有Qt支持的類型,比較貼心的是,數(shù)據(jù)可以分成多個(gè)角色(role),例如Qt::DisplayRole專用于顯示,Qt::BackgroundRole用于顯示背景色等等。所以在model中,你不光可以對(duì)“肉”進(jìn)行編號(hào),還可以對(duì)“肉”進(jìn)行“深加工”,使它們更“好看”或是更“美味”。View組織這些數(shù)據(jù)并顯示,但卻沒(méi)有做真正的顯示工作,真正的工作留給了delegate。Delegate就是MVC中的Coview讓它顯示時(shí)它就在paint函數(shù)中顯示。當(dāng)然,你可以重載這個(gè)函數(shù)并實(shí)現(xiàn)你自己的顯示。你還可以給一個(gè)view設(shè)定rowdelegate和columdelegate專用于row和colum。當(dāng)用戶觸發(fā)了view的edittrigger時(shí)(如雙擊鼠標(biāo)或回車),view開(kāi)始inplaceedit(beginEditing)。Delegate會(huì)在合適的地方創(chuàng)建一個(gè)合適的widget(如lineedit或combobox等)處理用戶的輸入,用戶輸入完成以后delegate獲取用戶的輸入并返回。這些輸入可以通過(guò)調(diào)用model的setData函數(shù)保存到真正的"肉"中。所以Delegate其實(shí)就是負(fù)責(zé)最終顯示數(shù)據(jù)和處理用戶交互的既然由用戶交互,最重要的肯定是用戶的選擇了。說(shuō)一下selectionmodel。View將用戶選擇的itemindex全部存入selectionmodel中,顯示的時(shí)候根據(jù)selectionmodel的內(nèi)容顯示。另外,多個(gè)view可以共享同一個(gè)selectionmodel,這樣,當(dāng)你選中其中的一個(gè)時(shí),另一個(gè)view中的相應(yīng)item也會(huì)被選中。QtModel/View/main-snapshot/model-view-programming.html介紹Qt4推出了一組新的itemview類,它們使用model/view結(jié)構(gòu)來(lái)管理數(shù)據(jù)與表示層的關(guān)系。這種結(jié)構(gòu)帶來(lái)的功能上的分離給了開(kāi)發(fā)人員更大的彈性來(lái)定制數(shù)據(jù)項(xiàng)的表示,它也提供一個(gè)標(biāo)準(zhǔn)的model接口,使得更多的數(shù)據(jù)源可以被這些itemview使用。這里對(duì)model/view的結(jié)構(gòu)進(jìn)行了描述,結(jié)構(gòu)中的每個(gè)組件都進(jìn)行了解釋,給出了一些例子說(shuō)明了提供的這些類如何使用。Model/View結(jié)構(gòu)Model-View-Controller(MVC),是從Smalltalk發(fā)展而來(lái)的一種設(shè)計(jì)模式,常被用于構(gòu)建用戶界面。經(jīng)典設(shè)計(jì)模式的著作中有這樣的描述:MVC由三種對(duì)象組成Model是應(yīng)用程序?qū)ο?,ew是它的屏幕表示,Controller定義了用戶界面如何對(duì)用戶輸入進(jìn)行響應(yīng)°MVC之前,用戶界面設(shè)計(jì)傾向于三者揉合在一起MVC對(duì)它們進(jìn)行了解耦,提高了靈活性與重用性。假如把view與controller結(jié)合在一起,結(jié)果就是model/view結(jié)構(gòu)。這個(gè)結(jié)構(gòu)依然是把數(shù)據(jù)存儲(chǔ)與數(shù)據(jù)表示進(jìn)行了分離,它與MVC都基于同樣的思想,但它更簡(jiǎn)單一些。這種分離使得在幾個(gè)不同的view上顯示同一個(gè)數(shù)據(jù)成為可能,也可以重新實(shí)現(xiàn)新的view,而不必改變底層的數(shù)據(jù)結(jié)構(gòu)。為了更靈活的對(duì)用戶輸入進(jìn)行處理,引入了delegate這個(gè)概念。它的好處是,數(shù)據(jù)項(xiàng)的渲染與編程可以進(jìn)行定制。如上圖所示,model與數(shù)據(jù)源通訊,并提供接口給結(jié)構(gòu)中的別的組件使用。通訊的性質(zhì)依賴于數(shù)據(jù)源的種類與model實(shí)現(xiàn)的方式。view從model獲取modelindexes,后者是數(shù)據(jù)項(xiàng)的引用。通過(guò)把modelindexes提供給model,view可以從數(shù)據(jù)源中獲取數(shù)據(jù)。在標(biāo)準(zhǔn)的views中,delegate會(huì)對(duì)數(shù)據(jù)項(xiàng)進(jìn)行渲染,當(dāng)某個(gè)數(shù)據(jù)項(xiàng)被選中時(shí),delegate通過(guò)modelindexes與model直接進(jìn)行交流??偟膩?lái)說(shuō),model/view相關(guān)類可以被分成上面所提到的三組:models,views,delegates。這些組件通過(guò)抽象類來(lái)定義,它們提供了共同的接口,在某些情況下,還提供了缺省的實(shí)現(xiàn)。抽象類意味著需要子類化以提供完整的其他組件希望的功能。這也允許實(shí)現(xiàn)定制的組件。models,views,delegates之間通過(guò)信號(hào),槽機(jī)制來(lái)進(jìn)行通訊:從model發(fā)出的信號(hào)通知view數(shù)據(jù)源中的數(shù)據(jù)發(fā)生了改變。從view發(fā)出的信號(hào)提供了有關(guān)被顯示的數(shù)據(jù)項(xiàng)與用戶交互的信息。從delegate發(fā)生的信號(hào)被用于在編輯時(shí)通知model和view關(guān)于當(dāng)前編輯器的狀態(tài)信息。Models所有的itemmodels都基于QAbstractltemModel類,這個(gè)類定義了用于views和delegates訪問(wèn)數(shù)據(jù)的接口。數(shù)據(jù)本身不必存儲(chǔ)在model,數(shù)據(jù)可被置于一個(gè)數(shù)據(jù)結(jié)構(gòu)或另外的類,文件,數(shù)據(jù)庫(kù),或別的程序組件中。關(guān)于model的基本概念在ModelClasses部分中描述。QAbstractItemModel提供給數(shù)據(jù)一個(gè)接口,它非常靈活,基本滿足views的需要,無(wú)論數(shù)據(jù)用以下任何樣的形式表現(xiàn),如tables,lists,trees。然而,當(dāng)你重新實(shí)現(xiàn)一個(gè)model時(shí),如果它基于table或list形式的數(shù)據(jù)結(jié)構(gòu),最好從QAbstractListModel,QAbstractTableModel開(kāi)始做起,因?yàn)樗鼈兲峁┝诉m當(dāng)?shù)某R?guī)功能的缺省實(shí)現(xiàn)。這些類可以被子類化以支持特殊的定制需求。子類化model的過(guò)程在CreateNewModel部分討論QT提供了一些現(xiàn)成的models用于處理數(shù)據(jù)項(xiàng):QStringListModel用于存儲(chǔ)簡(jiǎn)單的QString列表。QStandardltemModel管理復(fù)雜的樹(shù)型結(jié)構(gòu)數(shù)據(jù)項(xiàng),每項(xiàng)都可以包含任意數(shù)據(jù)。QDirModel提供本地文件系統(tǒng)中的文件與目錄信息。QSqlQueryModel,QSqlTableModel,QSqlRelationTableModel用來(lái)訪問(wèn)數(shù)據(jù)庫(kù)。假如這些標(biāo)準(zhǔn)Model不滿足你的需要,你應(yīng)該子類化QAbstractItemModel,QAbstractListModel或是QAbstractTableModel來(lái)定制。Views不同的view都完整實(shí)現(xiàn)了各自的功能QListView把數(shù)據(jù)顯示為一個(gè)列表,QTableView把Model中的數(shù)據(jù)以table的形式表現(xiàn),QTreeView用具有層次結(jié)構(gòu)的列表來(lái)顯示model中的數(shù)據(jù)。這些類都基于QAbstractltemView抽象基類,盡管這些類都是現(xiàn)成的,完整的進(jìn)行了實(shí)現(xiàn),但它們都可以用于子類化以便滿足定制需求。DelegatesQAbstractItemDelegate是model/view架構(gòu)中的用于delegate的抽象基類。缺省的delegate實(shí)現(xiàn)在QltemDelegate類中提供。它可以用于Qt標(biāo)準(zhǔn)views的缺省delegate.排序在model/view架構(gòu)中,有兩種方法進(jìn)行排序,選擇哪種方法依賴于你的底層Model。假如你的model是可排序的,也就是它重新實(shí)現(xiàn)了QAbstractltemModel::sort()函數(shù)QTableView與QTreeView都提供了API,允許你以編程的方式對(duì)Model數(shù)據(jù)進(jìn)行排序。另外,你也可以進(jìn)行交互方式下的排序(例如,允許用戶通過(guò)點(diǎn)擊view表頭的方式對(duì)數(shù)據(jù)進(jìn)行排序),可以這樣做:把QHeaderView::sectionClicked()信號(hào)與QTableView::sortByColum()槽或QTreeView::sortByColumn()槽進(jìn)行聯(lián)結(jié)就好了。另一種方法是,假如你的model沒(méi)有提供需要的接口或是你想用listview表示數(shù)據(jù),可以用一個(gè)代理model在用view表示數(shù)據(jù)之前對(duì)你的model數(shù)據(jù)結(jié)構(gòu)進(jìn)行轉(zhuǎn)換。便利類許多便利類都源于標(biāo)準(zhǔn)的view類,它們方便了那些使用Qt中基于項(xiàng)的view與table類,它們不應(yīng)該被子類化,它們只是為Qt3的等價(jià)類提供一個(gè)熟悉的接口。這些類有QListWidget,QTreeWidget,QTableWidget,它們提供了如Qt3中的QListBox,QlistView,QTable相似的行為。這些類比View類缺少靈活性,不能用于任意的models,推介使用model/view的方法處理數(shù)據(jù)。介紹Qt提供了兩個(gè)標(biāo)準(zhǔn)的models:QStandardltemModel和QDirModelQStandardltemModel是一個(gè)多用途的model,可用于表示list,table,treeviews所需要的各種不同的數(shù)據(jù)結(jié)構(gòu)。這個(gè)model也持有數(shù)據(jù)。QDirModel維護(hù)相關(guān)的目錄內(nèi)容的信息,它本身不持有數(shù)據(jù),僅是對(duì)本地文件系統(tǒng)中的文件與目錄的描述。QDirModel是一個(gè)現(xiàn)成的model,很容易進(jìn)行配置以用于現(xiàn)存的數(shù)據(jù),使用這個(gè)model,可以很好地展示如何給一個(gè)現(xiàn)成的view設(shè)定model,研究如何用modelindexes來(lái)操縱數(shù)據(jù)。model與views的搭配使用QListView與QTreeView很適合與QDirModel搭配。下面的例子在treeview與listview顯示了相同的信息QDirModel提供了目錄內(nèi)容數(shù)據(jù)。這兩個(gè)Views共享用戶選擇,因此每個(gè)被選擇的項(xiàng)在每個(gè)view中都會(huì)被咼亮?!鐾瑇Twoviewsontothesamedirectorymodel■■N^me沁|Type|Modified_extensions上J3280Direclary2004-04-19T12:...』FAQ2080Dir&ct&ry2004-04-19T12:...Qjinclude由臥佬nsion5104Directory2OOW19T12;,.,fllNSTALLrOFAQ7777FAQFile2OO4-O4-13T12...□lib申“_indude10640Dirertary2OD4-O4-19T12:..._JLICENSE.GPLhDINSTALL4482INSTALLFile2OO4-O4-19T12..._JLICENSE.QPL白“_』ib72DirEdory2004-04-19T12:,.,_JMakefile:由」72Directory2004-04-19T12:...□MANIFEST744Dirprtory2004-04-19T12:..._nnksp-ecs=:■JREADME63READMEFile2004-04-19T12:,.,_||3iC5hJLICENSE.GPL18361GPLFile2OD4-O4-19T12:...」PLATFORMS”二|LI匚ENSE.QPL4689QPLFile2OD4-O4-19T12:..._pluginsL-[1Makefile2751File2OO3-O8-11T1G:...^1_qrnalce屮|111JREADMEzl先裝配出一個(gè)QDirModel以供使用,再創(chuàng)建views去顯示目錄的內(nèi)容。這給我展示了使用model的最簡(jiǎn)單的方式。model的創(chuàng)建與使用都在main()函數(shù)中完成:intmain(intargc,char*argv[]){QApplicationapp(argc,argv);QSplitter*splitter=newQSplitter;QDirModel*model=newQDirModel;〃從缺省目錄創(chuàng)建數(shù)據(jù)QTreeView*tree=newQTreeView(splitter);tree->setModel(model);tree->setRootlndex(model->index(QDir::currentPath()));QListView*list=newQListView(splitter);list->setModel(model);list->setRootlndex(model->index(QDir::currentPath()));〃配置一個(gè)view去顯示model中的數(shù)據(jù),只需要簡(jiǎn)單地調(diào)用setModel(),并把目錄model作為參數(shù)傳遞〃setRootlndex()告訴views顯示哪個(gè)目錄的信息,這需要提供一個(gè)modelindex,然后用這個(gè)//modelindex去model中去獲取數(shù)據(jù)//index()這個(gè)函數(shù)是QDirModel特有的,通過(guò)把一個(gè)目錄做為參數(shù),得到了需要的modelindex//其他的代碼只是窗口show出來(lái),進(jìn)入程序的事件循環(huán)就好了splitter->setWindowTitle("Twoviewsontothesamedirectorymodel");splitter->show();returnapp.exec();}上面的例子并沒(méi)有展示如何處理數(shù)據(jù)項(xiàng)的選擇,這包括很多細(xì)節(jié),以后會(huì)提到。Model類基本概念在model/view構(gòu)架中,model為view和delegates使用數(shù)據(jù)提供了標(biāo)準(zhǔn)接口。在Qt中,標(biāo)準(zhǔn)接口QAbstractltemModel類中被定義。不管數(shù)據(jù)在底層以何種數(shù)據(jù)結(jié)構(gòu)存儲(chǔ),QAabstractltemModel的子類會(huì)以層次結(jié)構(gòu)的形式來(lái)表示數(shù)據(jù),結(jié)構(gòu)中包含了數(shù)據(jù)項(xiàng)表。我們按這種約定來(lái)訪問(wèn)model中的數(shù)據(jù)項(xiàng),但這個(gè)約定不會(huì)對(duì)如何顯示這些數(shù)據(jù)有任何限制。數(shù)據(jù)發(fā)生改變時(shí),model通過(guò)信號(hào)槽機(jī)制來(lái)通知關(guān)聯(lián)的views0LisftModelTabkM-oddTreeModel1Root加ncQcmnwWcokjmn卜1cocpn;01HootitefnModelIndexes為了使數(shù)據(jù)存儲(chǔ)與數(shù)據(jù)訪問(wèn)分開(kāi),引入了modelindex的概念。通過(guò)modelindex,可以引用model中的數(shù)據(jù)項(xiàng),Views和delegates都使用indexes來(lái)訪問(wèn)數(shù)據(jù)項(xiàng),然后再顯示出來(lái)。因此,只有model需要了解如何獲取數(shù)據(jù),被model管理的數(shù)據(jù)類型可以非常廣泛地被定義。Modelindexes包含一個(gè)指向創(chuàng)建它們的model的指針,這會(huì)在配合多個(gè)model工作時(shí)避免混亂。QAbstractltemModel*model=index.model();modelindexes提供了對(duì)一項(xiàng)數(shù)據(jù)信息的臨時(shí)引用,通過(guò)它可以訪問(wèn)或是修改model中的數(shù)據(jù)。既然model有時(shí)會(huì)重新組織內(nèi)部的數(shù)據(jù)結(jié)構(gòu),這時(shí)modelindexes便會(huì)失效,因此不應(yīng)該保存臨時(shí)的modelindexes。假如需要一個(gè)對(duì)數(shù)據(jù)信息的長(zhǎng)期的引用,那么應(yīng)該創(chuàng)建一個(gè)persistentmodelindex。這個(gè)引用會(huì)保持更新。臨時(shí)的modelindexes由QModelIndex提供,而具有持久能力的modelindexes則由QPersistentModelIndex提供。在獲取對(duì)應(yīng)一個(gè)數(shù)據(jù)項(xiàng)的modelindex時(shí),需要考慮有關(guān)于model的三個(gè)屬性:行數(shù),列數(shù),父項(xiàng)的modelindex。行與列在最基本的形式中,一個(gè)model可作為一個(gè)簡(jiǎn)單的表來(lái)訪問(wèn),每個(gè)數(shù)據(jù)項(xiàng)由行,列數(shù)來(lái)定位。這必不意味著底層的數(shù)據(jù)用數(shù)組結(jié)構(gòu)來(lái)存儲(chǔ)。行和列的使用僅僅是一種約定,它允許組件之間相互通訊??梢酝ㄟ^(guò)指定model中的行列數(shù)來(lái)獲取任一項(xiàng)數(shù)據(jù),可以得到與數(shù)據(jù)項(xiàng)一一對(duì)應(yīng)的那個(gè)index。QModelIndexindex=model->index(row,column,...);Model為簡(jiǎn)單的,單級(jí)的數(shù)據(jù)結(jié)構(gòu)如list與tables提供了接口,它們?nèi)缟厦娲a所顯示的那樣,不再需要?jiǎng)e的信息被提供。當(dāng)我們?cè)讷@取一個(gè)
modelindex時(shí),我們需要提供另外的信息。T^bleModelABCHootiterrtrowABCHootiterrtrow-0row=1row-2row-3上圖代表一個(gè)基本的tablemodel,它的每一項(xiàng)用一對(duì)行列數(shù)來(lái)定位。通過(guò)行列數(shù),可以獲取代表一個(gè)數(shù)據(jù)項(xiàng)的modelindex.QModellndexindexA=model->index(0,0,QModellndex());QModellndexindexB=model->index(1,1,QModelIndex());QModellndexindexC=model->index(2,1,QModelIndex());一個(gè)model的頂級(jí)項(xiàng),由QModelIndex()取得,它們上式被用作父項(xiàng)。父項(xiàng)類似于表的接口在搭配使用table或listview時(shí)理想的,這種行列系統(tǒng)與view顯示的方式是確切匹配的。然則,像treeviews這種結(jié)構(gòu)需要model提供更為靈活的接口來(lái)訪問(wèn)數(shù)據(jù)項(xiàng)。每個(gè)數(shù)據(jù)項(xiàng)可能是別的項(xiàng)的父項(xiàng),上級(jí)的項(xiàng)可以獲取下級(jí)項(xiàng)的列表。當(dāng)獲取model中數(shù)據(jù)項(xiàng)的index時(shí),我們必須指定關(guān)于數(shù)據(jù)項(xiàng)的父項(xiàng)的信息。在model外部,引用一個(gè)數(shù)據(jù)項(xiàng)的唯一方法就是通過(guò)modelindex,因此需要在求取modelindex時(shí)指定父項(xiàng)的信息。QModellndexindex=model->index(row,column,parent);上圖中,A項(xiàng)和C項(xiàng)作為model中頂層的兄弟項(xiàng):QModelIndexindexA=model->index(0,0,QModellndex());QModelIndexindexC=model->index(2,1,QModelIndex());A有許多孩子,它的一個(gè)孩子B用以下代碼獲?。篞ModelIndexindexB=model->index(1,0,indexA);項(xiàng)角色model中的項(xiàng)可以作為各種角色來(lái)使用,這允許為不同的環(huán)境提供不同的數(shù)據(jù)。舉例來(lái)說(shuō),Qt::DisplayRole被用于訪問(wèn)一個(gè)字符串,它作為文本會(huì)在view中顯示。典型地,每個(gè)數(shù)據(jù)項(xiàng)都可以為許多不同的角色提供數(shù)據(jù),標(biāo)準(zhǔn)的角色在Qt::ItemDataRole中定義。我們可以通過(guò)指定modelindex與角色來(lái)獲取我們需要的數(shù)據(jù):QVariantvalue=model->data(index,role);角色指出了從model中引用哪種類型的數(shù)據(jù)。views可以用不同的形式顯示角色,因此為每個(gè)角色提供正確的信息是非常重要的。通過(guò)為每個(gè)角色提供適當(dāng)數(shù)據(jù),model也為views和delegates提供了暗示,如何正確地把這些數(shù)據(jù)項(xiàng)顯給用戶。不同的views可以自由地解析或忽略這些數(shù)據(jù)信息,對(duì)于特殊的場(chǎng)合,也可以定義一些附加的角色。概念總結(jié):1,Modelindexes為views與delegages提供model中數(shù)據(jù)項(xiàng)定位的信息,它與底層的數(shù)據(jù)結(jié)構(gòu)無(wú)關(guān)。通過(guò)指定行,列數(shù),父項(xiàng)的modelindex來(lái)引用數(shù)據(jù)項(xiàng)。依照別的組件的要求,modelindexes被model構(gòu)建。使用index()時(shí),如果指定了有效的父項(xiàng)的modelindex,那么返回得到的modelindex對(duì)應(yīng)于父項(xiàng)的某個(gè)孩子。使用index()時(shí),如果指定了無(wú)效的父項(xiàng)的modelindex,那么返回得到的modelindex對(duì)應(yīng)于頂層項(xiàng)的某個(gè)孩子。6,角色對(duì)一個(gè)數(shù)據(jù)項(xiàng)包含的不同類型的數(shù)據(jù)給出了區(qū)分。使用ModelIndexesQDirModel*model=newQDirModel;QModellndexparentindex=model->index(QDir::currentPath());intnumRows=model->rowCount(parentlndex);for(introw=0;row<numRows;++row){QModelIndexindex=model->index(row,0,parentIndex);tringtext=model->data(index,Qt::DisplayRole).toString();//Displaythetextinawidget.}以上的例子說(shuō)明了從model中獲取數(shù)據(jù)的基本原則:1,model的尺寸可以從rowCount()與columnCount()中得出。這些函數(shù)通常都需要一個(gè)表示父項(xiàng)的modelindex。2,modelindexes用來(lái)從model中訪問(wèn)數(shù)據(jù)項(xiàng),數(shù)據(jù)項(xiàng)用行,列,父項(xiàng)modelindex定位。為了訪問(wèn)model頂層項(xiàng),可以使用QModelIndex()指定。數(shù)據(jù)項(xiàng)為不同的角色提供不同的數(shù)據(jù)。為了獲取數(shù)據(jù),除了modelindex之外,還要指定角色。創(chuàng)建新的Models介紹model/view組件之間功能的分離,允許創(chuàng)建model利用現(xiàn)成的views。這也可以使用標(biāo)準(zhǔn)的功能圖形用戶接口組件像QListView,QTableView和QTreeView來(lái)顯示來(lái)自各種數(shù)據(jù)源的數(shù)據(jù)為。QAbstractListModel類提供了非常靈活的接口,允許數(shù)據(jù)源以層次結(jié)構(gòu)的形式來(lái)管理信息,也允許以某種方式對(duì)數(shù)據(jù)進(jìn)行插入、刪除、修改和存儲(chǔ)。它也提供了對(duì)拖拽操作的支持。QAbstractListModel與QAbstractTableModel為簡(jiǎn)單的非層次結(jié)構(gòu)的數(shù)據(jù)提供了接口,對(duì)于比較簡(jiǎn)單的list和tablemodels來(lái)說(shuō),這是不錯(cuò)的一個(gè)開(kāi)始點(diǎn)。設(shè)計(jì)一個(gè)Model當(dāng)我們?yōu)榇嬖诘臄?shù)據(jù)結(jié)構(gòu)新建一個(gè)model時(shí),首先要考慮的問(wèn)題是應(yīng)該選用哪種model來(lái)為這些數(shù)據(jù)提供接口。假如數(shù)據(jù)結(jié)構(gòu)可以用數(shù)據(jù)項(xiàng)的列表或表來(lái)表示,那么可以考慮子類化QAbstractListModel或QAbstractTableModel,既然這些類已經(jīng)合理地對(duì)許多功能提供缺省實(shí)現(xiàn)。然而,假如底層的數(shù)據(jù)結(jié)構(gòu)只能表示成具有層次結(jié)構(gòu)的樹(shù)型結(jié)構(gòu),那么必須得子類化QAbstractItemModel無(wú)論底層的數(shù)據(jù)結(jié)構(gòu)采取何種形式,在特定的model中實(shí)現(xiàn)標(biāo)準(zhǔn)的QAbstractItemModelAPI總是一個(gè)不錯(cuò)的主意,這使得可以使用更自然的方式對(duì)底層的數(shù)據(jù)結(jié)構(gòu)進(jìn)行訪問(wèn)。這也使得用數(shù)據(jù)構(gòu)建model更為容易,其他的model/view組件也可以使用標(biāo)準(zhǔn)的API與之進(jìn)行交互。一個(gè)只讀model示例這個(gè)示例實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的,非層次結(jié)構(gòu)的,只讀的數(shù)據(jù)model,它基于QStringistModel類。它有一個(gè)QStringList作為它內(nèi)部的數(shù)據(jù)源,只實(shí)現(xiàn)了一些必要的接口。為了簡(jiǎn)單化,它子類化了QAbstractListModel,這個(gè)基類提供了合理的缺省行為,對(duì)外提供了比QAbstractItemModel更為簡(jiǎn)單的接口。當(dāng)我們實(shí)現(xiàn)一個(gè)model時(shí),不要忘了QAbstractItemModel本身不存儲(chǔ)任何數(shù)據(jù),它僅僅提供了給views訪問(wèn)數(shù)據(jù)的接口。classStringListModel:publicQAbstractListModel{Q_OBJECTpublic:StringListModel(constQStringList&strings,QObject*parent=0):QAbstractListModel(parent),stringList(strings){}introwCount(constQModelIndex&parent=QModellndex())const;QVariantdata(constQModelIndex&index,introle)const;QVariantheaderData(intsection,Qt::Orientationorientation,introle=Qt::DisplayRole)const;private:QStringListstringList;};除了構(gòu)造函數(shù),我們僅需要實(shí)現(xiàn)兩個(gè)函數(shù):rowCount()返回model中的行數(shù),data()返回與特定modelindex對(duì)應(yīng)的數(shù)據(jù)項(xiàng)。具有良好行為的model也會(huì)實(shí)現(xiàn)headerData(),它返回tree和tableviews需要的,在標(biāo)題中顯示的數(shù)據(jù)。因?yàn)檫@是一個(gè)非層次結(jié)構(gòu)的model,我們不必考慮父子關(guān)系。假如model具有層次結(jié)構(gòu),我們也應(yīng)該實(shí)現(xiàn)index()與parent()函數(shù)。Model的尺寸我們認(rèn)為model中的行數(shù)與stringlist中的string數(shù)目一致:intStringListModel::rowCount(constQModellndex&parent)const{returnstringList.count();}在缺省情況下,從QAbstractListModel派生的model只具有一列,因此不需要實(shí)現(xiàn)columnCount()。Model標(biāo)題與數(shù)據(jù)QVariantStringListModel::data(constQModelIndex&index,introle)const{if(!index.isValid())returnQVariant();if(index.row()>=stringList.size())returnQVariant();if(role==Qt::DisplayRole)returnstringList.at(index.row());elsereturnQVariant();}QVariantStringListModel::headerData(intsection,Qt::Orientationorientation,introle)const{if(role!=Qt::DisplayRole)returnQVariant();if(orientation==Qt::Horizontal)returnQString("Column%1").arg(section);elsereturnQString("Row%1").arg(section);}一個(gè)數(shù)據(jù)項(xiàng)可能有多個(gè)角色,根據(jù)角色的不同輸出不同的數(shù)據(jù)。上例中,model中的數(shù)據(jù)項(xiàng)只有一個(gè)角色,DisplayRole,然而我們也可以重用提供給DisplayRole的數(shù)據(jù),作為別的角色使用,如我們可以作為T(mén)oolTipRole來(lái)用。可編輯的model上面我們演示了一個(gè)只讀的model,它只用于向用戶顯示,對(duì)于許多程序來(lái)說(shuō),可編輯的listmodel可能更有用。我們只需要給只讀的model提供另外兩個(gè)函數(shù)flags()與setData()的實(shí)現(xiàn)。下列函數(shù)聲明被添加到類定義中:Qt::ltemFlagsflags(constQModelIndex&index)const;boolsetData(constQModelIndex&index,constQVariant&value,introle=Qt::EditRole);讓model可編輯delegate會(huì)在創(chuàng)建編輯器之前檢查數(shù)據(jù)項(xiàng)是否是可編輯的。model必須得讓delegate知道它的數(shù)據(jù)項(xiàng)是可編輯的。這可以通過(guò)為每一個(gè)數(shù)據(jù)項(xiàng)返回一個(gè)正確的標(biāo)記得到,在本例中,我們假設(shè)所有的數(shù)據(jù)項(xiàng)都是可編輯可選擇的:Qt::ItemFlagsStringListModel::flags(constQModelIndex&ndex)const{if(!index.isValid())returnQt::ltemlsEnabled;returnQAbstractltemModel::flags(index)|Qt::ItemIsEditable;}我們不必知道delegate執(zhí)行怎樣實(shí)際的編輯處理過(guò)程,我們只需提供給delegate一個(gè)方法,delegate會(huì)使用它對(duì)model中的數(shù)據(jù)進(jìn)行設(shè)置。這個(gè)特殊的函數(shù)就是setData():boolStringListModel::setData(constQModelIndex&ndex,constQVariant&value,introle){if(index.isValid()&&role==Qt::EditRole){stringList.replace(index.row(),value.toString());emitdataChanged(index,index);returntrue;}returnfalse;}當(dāng)數(shù)據(jù)被設(shè)置后,model必須得讓views知道一些數(shù)據(jù)發(fā)生了變化,這可通過(guò)發(fā)射一個(gè)dataChanged()信號(hào)實(shí)現(xiàn)。因?yàn)橹挥幸粋€(gè)數(shù)據(jù)項(xiàng)發(fā)生了變化,因此在信號(hào)中說(shuō)明的變化范圍只限于一個(gè)modelindex。插入,刪除行在model中改變行數(shù)與列數(shù)是可能的。當(dāng)然在本列中,只考慮行的情況,我們只需要重新實(shí)現(xiàn)插入、刪除的函數(shù)就可以了,下面應(yīng)在類定義中聲明:boolinsertRows(intposition,introws,constQModelIndex&index=QModelIndex());boolremoveRows(intposition,introws,constQModelIndex&index=QModelIndex());既然model中的每行對(duì)應(yīng)于列表中的一個(gè)string,因此,insertRows()函數(shù)在stringlist中指定位置插入一個(gè)空string,父index通常用于決定model中行列的位置,本例中只有一個(gè)單獨(dú)的頂級(jí)項(xiàng),困此只需要在list中插入空string0boolStringListModel::insertRows(intposition,introws,constQModellndex&parent){beginlnsertRows(QModellndex(),position,position+rows-1);for(introw=0;row<rows;++row){stringList.insert(position,"");}endInsertRows();returntrue;}beginInsertRows()通知其他組件行數(shù)將會(huì)改變。endInsertRows()對(duì)操作進(jìn)行確認(rèn)與通知。返回true表示成功。刪除操作與插入操作類似:boolStringListModel::removeRows(intposition,introws,constQModelIndex&parent){beginRemoveRows(QModellndex(),position,position+rows-1);for(introw=0;row<rows;++row){stringList.removeAt(position);}endRemoveRows();returntrue;}View類概念在model/view架構(gòu)中,view從model中獲得數(shù)據(jù)項(xiàng)然后顯示給用戶。數(shù)據(jù)顯示的方式不必與model提供的表示方式相同,可以與底層存儲(chǔ)數(shù)據(jù)項(xiàng)的數(shù)據(jù)結(jié)構(gòu)完全不同。內(nèi)容與顯式的分離是通過(guò)由QAbstractltemModel提供的標(biāo)準(zhǔn)模型接口,由QAsbstractltemview提供的標(biāo)準(zhǔn)視圖接口共同實(shí)現(xiàn)的。普遍使用modelindex來(lái)表示數(shù)據(jù)項(xiàng)0view負(fù)責(zé)管理從model中讀取的數(shù)據(jù)的外觀布局。它們自己可以去渲染每個(gè)數(shù)據(jù)項(xiàng),也可以利用delegate來(lái)既處理渲染又進(jìn)行編輯。除了顯示數(shù)據(jù),views也處理數(shù)據(jù)項(xiàng)的導(dǎo)航,參與有關(guān)于數(shù)據(jù)項(xiàng)選擇的部分功能。view也實(shí)現(xiàn)一些基本的用戶接口特性,如上下文菜單與拖拽功能。view也為數(shù)據(jù)項(xiàng)提供了缺省的編程功能,也可搭配delegate實(shí)現(xiàn)更為特殊的定制編輯的需求。一個(gè)view創(chuàng)建時(shí)必不需要model,但在它能顯示一些真正有用的信息之前,必須提供一個(gè)model。view通過(guò)使用selections來(lái)跟蹤用戶選擇的數(shù)據(jù)項(xiàng)。每個(gè)view可以維護(hù)單獨(dú)使用的selections,也可以在多個(gè)views之間共享。有些views,如QTableView和QTreeView,除數(shù)據(jù)項(xiàng)之外也可顯示標(biāo)題(Headers),標(biāo)題部分通過(guò)一個(gè)view來(lái)實(shí)現(xiàn),QHeaderView。標(biāo)題與view—樣總是從相同的model
中獲取數(shù)據(jù)。從modeI中獲取數(shù)據(jù)的函數(shù)是QabstractltemModel::headerDate(),—般總是以表單的形式中顯示標(biāo)題信息??梢詮腝HeaderView子類化,以實(shí)現(xiàn)更為復(fù)雜的定制化需求。使用現(xiàn)成的viewQt提供了三個(gè)現(xiàn)成的view類,它們能夠以用戶熟悉的方式顯示model中的數(shù)據(jù)。QListView把model中的數(shù)據(jù)項(xiàng)以一個(gè)簡(jiǎn)單的列表的形式顯示,或是以經(jīng)典的圖標(biāo)視圖的形式顯示。QTreeView把model中的數(shù)據(jù)項(xiàng)作為具有層次結(jié)構(gòu)的列表的形式顯示,它允許以緊湊的深度嵌套的結(jié)構(gòu)進(jìn)行顯示。QTableView卻是把model中的數(shù)據(jù)項(xiàng)以表格的形式展現(xiàn),更像是一個(gè)電子表格應(yīng)用程序的外觀布局。ii1”曲,ii1”曲,JnewJffiw.pra斶[締除IbjDhAiyQJ.0聆曲腎M嬸,1JvwvltwAb41(-I—1J以上這些標(biāo)準(zhǔn)view的行為足以應(yīng)付大多數(shù)的應(yīng)用程序,它們也提供了一些基本的編輯功能,也可以定制特殊的需求。使用model以前的例子中創(chuàng)建過(guò)一個(gè)stringlistmodel,可以給它設(shè)置一些數(shù)據(jù),再創(chuàng)建一個(gè)view把model中的內(nèi)容展示出來(lái):intmain(intargc,char*argv[]){QApplicationapp(argc,argv);//Unindentedforquotingpurposes:QStringListnumbers;numbers<<"One"<<"Two"<<"Three"<<"Four"<<"Five";QAbstractltemModel*model=newStringListModel(numbers);〃要注意的是,這里把StringListModel作為一個(gè)QAbstractItemModel來(lái)使用。這樣我們就可以〃使用model中的抽象接口,而且如果將來(lái)我們用別的model代替了當(dāng)前這個(gè)model,這些代碼也會(huì)照樣工作。//QListView提供的列表視圖足以滿足當(dāng)前這個(gè)model的需要了。QListView*view=newQListView;view->setModel(model);view->show();returnapp.exec();}view會(huì)渲染model中的內(nèi)容,通過(guò)model的接口來(lái)訪問(wèn)它的數(shù)據(jù)。當(dāng)用戶試圖編輯數(shù)據(jù)項(xiàng)時(shí),view會(huì)使用缺省的delegate來(lái)提供一個(gè)編輯構(gòu)件。一個(gè)model,多個(gè)views為多個(gè)views提供相同的model是非常簡(jiǎn)單的事情,只要為每個(gè)view
設(shè)置相同的model。QTableView*firstTableView=newQTableView;QTableView*secondTableView=newQTableView;firstTableView->setModel(model);secondTableView->setModel(model);在model/view架構(gòu)中信號(hào)、槽機(jī)制的使用意味著model中發(fā)生的改變會(huì)傳遞中聯(lián)結(jié)的所有view中,這保證了不管我們使用哪個(gè)view,不管我們使用哪個(gè)view,訪問(wèn)的都是同樣的一份數(shù)據(jù)。上面的圖展示了一個(gè)model上的兩個(gè)不同的views,盡管在不同的view中顯示的model中的數(shù)據(jù)是一致的,每個(gè)view都維護(hù)它們自己的內(nèi)部選擇模型,但有時(shí)候在某些情況下,共享一個(gè)選擇模型也是合理的。處理數(shù)據(jù)項(xiàng)的選擇view中數(shù)據(jù)項(xiàng)選擇機(jī)制由QltemSelectionModel類提供。所有標(biāo)準(zhǔn)的view缺省都構(gòu)建它們自己的選擇模型,以標(biāo)準(zhǔn)的方式與它們交互。選擇模型可以用selectionModel()函數(shù)取得,替代的選擇模型也可以通過(guò)setSelectionModel()來(lái)設(shè)置。當(dāng)我們想在一個(gè)model上提供多個(gè)一致的views時(shí),這種對(duì)選擇模型的控制能力非常有用。通常來(lái)講,除非你子類化一個(gè)model或view,你不必直接操縱selections的內(nèi)容。多個(gè)views之間共享選擇接著上邊的例子,我們可以這樣:secondTableView->setSelectionModel(firstTableView->selectionModel());現(xiàn)在所有views都在同樣的選擇模型上操作,數(shù)據(jù)與選擇項(xiàng)都保持同步。上面的例子中,兩個(gè)view的類型是相同的,假如這兩個(gè)view類型不同,那么所選擇的數(shù)據(jù)項(xiàng)在每個(gè)view中的表現(xiàn)形式會(huì)有很大的不同。例如,在一個(gè)tableview中一個(gè)連續(xù)的選擇,在一個(gè)treeview中表現(xiàn)出來(lái)的可能會(huì)是幾個(gè)高亮的數(shù)據(jù)項(xiàng)片斷的組合。在views中選擇數(shù)據(jù)項(xiàng)概念用于新的view類中的選擇模型比Qt3中的模型有了很大的改進(jìn)。它為基于model/view架構(gòu)的選擇提供了更為全面的描述。盡管對(duì)提供了的views來(lái)說(shuō),負(fù)責(zé)操縱選擇的標(biāo)準(zhǔn)類已經(jīng)足以應(yīng)付,但是你也可以創(chuàng)建特定的選擇模型來(lái)滿足你特殊的需求。關(guān)于在view被選擇的數(shù)據(jù)項(xiàng)的信息保持在QltemSelectionModel類的實(shí)例中。它也為每個(gè)獨(dú)立的model中的數(shù)據(jù)項(xiàng)維護(hù)modelindexes信息,與任何views都關(guān)聯(lián)關(guān)系。既然一個(gè)model可用于多個(gè)views,那么在多個(gè)views之間共享選擇信息也是可以做到的,這使得多個(gè)views可以以一致的方式進(jìn)行顯示。選擇由多個(gè)選擇范圍組成。通過(guò)僅僅記錄開(kāi)始modelindexes與結(jié)束modelindexes,最大化地記錄了可以選擇的范圍。非連續(xù)選擇數(shù)據(jù)項(xiàng)由多個(gè)選擇范圍來(lái)描述。選擇模型記錄modelindexes的集合來(lái)描述一個(gè)選擇。最近選擇的數(shù)據(jù)項(xiàng)被稱為currentselection。應(yīng)用程序可以通過(guò)使用某種類型的選擇命令來(lái)修改選擇的效果。在進(jìn)行選擇操作時(shí),可以把QItemSelectionModel看成是model中所有數(shù)據(jù)項(xiàng)選擇狀態(tài)的一個(gè)記錄。一旦建立一個(gè)選擇模型,所有項(xiàng)的集合都可以選擇,撤消選擇,或者選擇狀態(tài)進(jìn)行切換而不需要知道哪個(gè)數(shù)據(jù)項(xiàng)是否已經(jīng)被選擇過(guò)。所有被選擇的項(xiàng)的indexes在任何時(shí)候都可以得到,通過(guò)信號(hào)槽機(jī)制可以通知?jiǎng)e的組件發(fā)生的變化。使用選擇模型標(biāo)準(zhǔn)view類提供了缺省的選擇模型,它們可以在大次數(shù)程序中使用。一個(gè)view中的選擇模型可以通過(guò)調(diào)用view的函數(shù)selectionModel()取得,也可以通過(guò)setSelectionModel()在多個(gè)views之間共享選擇模型,因此總的來(lái)說(shuō)構(gòu)建一個(gè)新的模型一般情況不太必要。通過(guò)給QltemSelection指定一個(gè)model,—對(duì)modelindexes,可以創(chuàng)建一個(gè)選擇。indexes的用法依賴于給定的model,這兩個(gè)indexes被解釋成選擇的區(qū)塊中的左上角項(xiàng)和右下角項(xiàng)。model中的項(xiàng)的選擇服從于選擇模型。選擇項(xiàng)構(gòu)建一個(gè)tablemodel,它有32個(gè)項(xiàng),用一個(gè)tableview進(jìn)行顯示:TableModel*model=newTableModel(8,4,&app);QTableView*table=newQTableView(O);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,QltemSelectionModel::Select);結(jié)果如下:讀取選擇狀態(tài)存儲(chǔ)在選擇模型中indexes可以用selectionlndexes()函數(shù)來(lái)讀取。它返回一個(gè)未排序的modelindexes列表,我們可以遍歷它,如果我們知道他們關(guān)聯(lián)于哪個(gè)model的話。QModellndexListindexes=selectionModel->selectedlndexes();QModellndexindex;foreach(index,indexes){QStringtext=QString(”(%1,%2)").arg(index.row()).arg(index.column());model->setData(index,text);}選擇模型在選擇發(fā)生變化時(shí)會(huì)發(fā)出信號(hào)。這用于通知?jiǎng)e的組件包括整體與當(dāng)前焦點(diǎn)項(xiàng)所發(fā)生的變化。我們可以連接selectionChanged()信號(hào)到一個(gè)槽,檢查當(dāng)信號(hào)產(chǎn)生時(shí)哪些項(xiàng)被選擇或被取消選擇。這個(gè)槽被調(diào)用時(shí)帶有兩個(gè)參數(shù),它們都是QItemSelection對(duì)象,一個(gè)包含新被選擇的項(xiàng),另一個(gè)包含新近被取消選擇的項(xiàng)。下面的代碼演示了給新選擇的項(xiàng)添加數(shù)據(jù)內(nèi)容,新近被取消選擇的項(xiàng)的內(nèi)容被清空。voidMainWindow::updateSelection(constQItemSelection&selected,constQItemSelection&deselected){QModellndexindex;QModellndexListitems=selected.indexes();foreach(index,items){QStringtext=QString(”(%1,%2)").arg(index.row()).arg(index.column());model->setData(index,text);}items=deselected.indexes();foreach(index,items)model->setData(index,"");}也可以通過(guò)響應(yīng)currentChanged()信號(hào)來(lái)跟蹤當(dāng)前焦點(diǎn)項(xiàng).對(duì)應(yīng)的槽就有兩個(gè)接收參數(shù),一個(gè)表示之前的焦點(diǎn),另一個(gè)表示當(dāng)前的焦點(diǎn)。voidMainWindow::changeCurrent(constQModelIndex¤t,constQModelIndex&previous){statusBar()->showMessage(tr("Movedfrom(%1,%2)to(%3,%4)").arg(previous.row()).arg(previous.column()).arg(current.row()).arg(current.column()));}更新選擇選擇指令是通過(guò)選擇標(biāo)志提供的,它被定義在QItemSelectionModel::SelectionFlag中。常用的有Select標(biāo)記,Toggle標(biāo)記,Deselect標(biāo)記‘Current標(biāo)記,Clear標(biāo)記,其意義一目了然。沿上面例子的結(jié)果執(zhí)行以下代碼:QltemSelectiontoggleSelection;topLeft=model->index(2,1,QModelIndex());bottomRight=model->index(7,3,QModelIndex());toggleSelection.select(topLeft,bottomRight);selectionModel->select(toggleSelection,QltemSelectionModel::Toggle);結(jié)果如下:缺省情況下,選擇指令只針對(duì)單個(gè)項(xiàng)(由modelindexes指定)。然而,選擇指令可以通過(guò)與另外標(biāo)記的結(jié)合來(lái)改變整行和整列。舉例來(lái)說(shuō),假如你只使用一個(gè)index來(lái)調(diào)用select(),但是用Select標(biāo)記與Rows標(biāo)記的組合,那么包括那個(gè)項(xiàng)的整行都將被選擇??匆韵率纠篞ItemSelectioncolumnSelection;topLeft=model->index(0,1,QModelIndex());bottomRight=model->index(0,2,QModelIndex());columnSelection.select(topLeft,bottomRight);selectionModel->select(columnSelection,QItemSelectionModel::Select|QltemSelectionModel::Columns);QItemSelectionrowSelection;topLeft=model->index(0,0,QModelIndex());bottomRight=model->index(1,0,QModelIndex());rowSelection.select(topLeft,bottomRight);selectionModel->select(rowSelection,QItemSelectionModel::Select|QItemSelectionModel::Rows);結(jié)果如下選擇模型中所有項(xiàng)為了選擇model中的所有項(xiàng),必須先得創(chuàng)建一個(gè)選擇,它包括當(dāng)前層次上的所有項(xiàng):QModellndextopLeft=model->index(0,0,parent);QModellndexbottomRight=model->index(model->rowCount(parent)-1,model->columnCount(parent)-1,parent);QItemSelectionselection(topLeft,bottomRight);selectionModel->select(selection,QltemSelectionModel::Select);頂級(jí)index可以這樣:QModelIndexparent=QModelIndex();對(duì)具有層次結(jié)構(gòu)的model來(lái)說(shuō),可以使用hasChildren()函數(shù)來(lái)決定給定項(xiàng)是否是其它項(xiàng)的父項(xiàng)。Delegate類概念與MVC模式不同,model/view結(jié)構(gòu)沒(méi)有用于與用戶交互的完全獨(dú)立的組件。一般來(lái)講,view負(fù)責(zé)把數(shù)據(jù)展示給用戶,也處理用戶的輸入。為了獲得更多的靈性性,交互通過(guò)delegagte執(zhí)行。它既提供輸入功能又負(fù)責(zé)渲染view中的每個(gè)數(shù)據(jù)項(xiàng)??刂芼elegates的標(biāo)準(zhǔn)接口在QAbstractltemDelegate類中定義。Delegates通過(guò)實(shí)現(xiàn)paint()和sizeHint()以達(dá)到渲染內(nèi)容的目的。然而,簡(jiǎn)單的基于widget的delegates,可以從QItemDelegate子類化,而不是QAbstractltemDelegate,這樣可以使用它提供的上述函數(shù)的缺省實(shí)現(xiàn)。delegate可以使用widget來(lái)處理編輯過(guò)程,也可以直接對(duì)事件進(jìn)行處理。使用現(xiàn)成的delegateQt提供的標(biāo)準(zhǔn)views都使用QItemDelegate的實(shí)例來(lái)提供編輯功能。它以普通的風(fēng)格來(lái)為每個(gè)標(biāo)準(zhǔn)view渲染數(shù)據(jù)項(xiàng)。這些標(biāo)準(zhǔn)的views包括:QListView,QTableView,QTreeView。所有標(biāo)準(zhǔn)的角色都通過(guò)標(biāo)準(zhǔn)views包含的缺省delegate進(jìn)行處理。一個(gè)view使用的delegate可以用itemDelegate()函數(shù)取得,而setItemDelegate()函數(shù)可以安裝一個(gè)定制delegateo一個(gè)簡(jiǎn)單的delegate這個(gè)delegate使用QSpinBox來(lái)提供編輯功能。它主要想用于顯示整數(shù)的models上。盡管我們已經(jīng)建立了一個(gè)基于整數(shù)的tablemodel,但我們也可以使用QStandardltemModel,因?yàn)閐elegate可以控制數(shù)據(jù)
溫馨提示
- 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ù)網(wǎng)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2022屆數(shù)學(xué)(文科)高考總復(fù)習(xí)-課時(shí)提升作業(yè)(二十六)-4.4平面向量應(yīng)用舉例
- 【狀元之路】2020-2021學(xué)年人教版高中地理選修5(B卷)同步練習(xí)-2-1
- 河北省廊坊市2025屆高三上學(xué)期期末考試英語(yǔ)試卷(含解析無(wú)聽(tīng)力音頻無(wú)聽(tīng)力原文)
- 【高考總動(dòng)員】2022屆高考政治一輪總復(fù)習(xí)課時(shí)作業(yè)39創(chuàng)新意識(shí)與社會(huì)進(jìn)步
- 《結(jié)直腸癌X線表現(xiàn)》課件
- 【2022走向高考】高三英語(yǔ)一輪(外研版)復(fù)習(xí):必修1-Module-4綜合測(cè)試
- 臨時(shí)排水工程施工方案
- 【創(chuàng)新設(shè)計(jì)】2021高考英語(yǔ)(江蘇專用)大二輪總復(fù)習(xí)定時(shí)訓(xùn)練6
- 【-學(xué)案導(dǎo)學(xué)設(shè)計(jì)】2020-2021學(xué)年高中物理(人教版-選修3-1)第1章-第3節(jié)-課時(shí)作業(yè)
- 二年級(jí)數(shù)學(xué)計(jì)算題專項(xiàng)練習(xí)集錦
- 中國(guó)地理空白圖(政區(qū)、分省輪廓、地形、鐵路空白圖)-(3)1
- 四川省成都市龍泉驛區(qū)2023-2024學(xué)年三年級(jí)數(shù)學(xué)第一學(xué)期期末監(jiān)測(cè)試題含答案
- 鍋爐控制器modbus協(xié)議支持說(shuō)明
- 粉末涂料有限公司危廢庫(kù)安全風(fēng)險(xiǎn)分級(jí)管控清單
- 750更換齒輪箱作業(yè)指導(dǎo)書(shū)
- GB/T 20706-2023可可粉質(zhì)量要求
- 安全生產(chǎn)信息管理制度全
- 猜歌名教學(xué)講解課件
- 世界主要國(guó)家洲別、名稱、首都、代碼、區(qū)號(hào)、時(shí)差匯總表
- 2023學(xué)年廣東省廣州市越秀區(qū)鐵一中學(xué)九年級(jí)(上)物理期末試題及答案解析
- 《報(bào)告文學(xué)研究》(07562)自考考試復(fù)習(xí)題庫(kù)(含答案)
評(píng)論
0/150
提交評(píng)論