Qt学习笔记-----Model/View架构
為了實(shí)現(xiàn)數(shù)據(jù)的存儲(chǔ)和表現(xiàn)分離,Qt提供了Model/View架構(gòu),包括三個(gè)部分,分別是模型(Model),視圖(View),委托(delegate)。
Model用于訪問底層數(shù)據(jù),也就是說為其他組件訪問存儲(chǔ)的數(shù)據(jù)提供了接口。
View通過Model Index來獲取底層的數(shù)據(jù),將數(shù)據(jù)繪制到窗體上。
Delegate是在View需要編輯的時(shí)候提供一種自定義編輯方式。比如我們可能只允許輸入數(shù)字,那么就需要委托來做這件事情。
三個(gè)部分只有Model知道怎么從內(nèi)存中讀取數(shù)據(jù),而View和Delegate則是借助Model Index通過Model來訪問。
對(duì)于View來說,它不需要知道底層數(shù)據(jù)是如何存儲(chǔ)的(這是Model的任務(wù)),它只需要從Model那里要來數(shù)據(jù),然后把數(shù)據(jù)放到屏幕上就可以了。
對(duì)于Model來說,它也不需要知道數(shù)據(jù)是怎么被表現(xiàn)在屏幕上的(那是View的任務(wù)),它只需要響應(yīng)View的請(qǐng)求,從內(nèi)存中找到數(shù)據(jù)然后告訴View就可以了。
對(duì)于Delegate來說,它什么都不需要知道,它只需要在某個(gè)組件需要編輯的時(shí)候,提供一個(gè)自定義的編譯器(如果有某種需求的話,比如只允許輸入數(shù)字),然后將編輯結(jié)果反饋給Model讓它來更改底層數(shù)據(jù),反饋給View讓它更新屏幕顯示即可。
Models, Views, Delegates三者之間的相互作用是通過信號(hào)槽來實(shí)現(xiàn)的:
1.由Model發(fā)出的信號(hào)告訴View底層數(shù)據(jù)發(fā)生了改變。
2.由View發(fā)出的信號(hào)提供用戶與窗體中元素之間交互的信息,比如說鼠標(biāo)點(diǎn)擊某個(gè)位置,需要編輯某個(gè)元素。
3.由Delegate發(fā)出的信號(hào)是在編輯某個(gè)元素時(shí)發(fā)出的,告訴Model和View編輯狀態(tài),比如編輯完成。
Model Classes:
Model提供一個(gè)標(biāo)準(zhǔn)的接口供View和Delegate訪問數(shù)據(jù),在Qt中,這個(gè)接口定義在QAbstractItemModel類中。
MV架構(gòu)中使用模型索引(Model Index)來確保數(shù)據(jù)的表現(xiàn)和它被存儲(chǔ)的方式之間相互分離。View和Delegate就是通過模型索引來請(qǐng)求Model獲取數(shù)據(jù)。因此,只有Model知道如何通過Model Index獲取數(shù)據(jù)。
一個(gè)完整的model index包括行索引,列索引和它父元素的model index。
View Classes:
在MV架構(gòu)中,View負(fù)責(zé)從Model那里獲取數(shù)據(jù)然后展現(xiàn)給用戶,數(shù)據(jù)被展現(xiàn)的方式是自定的,不需要考慮它在底層內(nèi)存是如何存儲(chǔ)的。況且View也根本不清楚這件事情。
View主要用于對(duì)需要展現(xiàn)給用戶的數(shù)據(jù)進(jìn)行布局,Qt也提供了一個(gè)標(biāo)準(zhǔn)視圖接口QAbstractItemView。
除了呈現(xiàn)給用戶數(shù)據(jù),View也承擔(dān)著數(shù)據(jù)選擇相關(guān)的責(zé)任,以及菜單和拖放的任務(wù)。View也具有編輯功能,如果不需要對(duì)用戶的輸入進(jìn)行控制,那么View自帶的編輯器就已經(jīng)足夠了。否則就需要只用Delegate委托生成一個(gè)編輯器來對(duì)用戶輸入進(jìn)行控制。
View使用setModel()來設(shè)置它的模型
Delegate Classes:
Delegate主要用于當(dāng)View中的元素需要編輯時(shí),提供自定義的編輯方式,實(shí)現(xiàn)對(duì)用戶輸入進(jìn)行控制。比如說只允許輸入數(shù)字等。委托的接口定義在QAbstractItemDelegate中。
當(dāng)View需要一個(gè)Delegate時(shí),那么用戶就需要自定義一個(gè)子類繼承委托接口。但是需要提供一些函數(shù):
createEditor()創(chuàng)建一個(gè)編輯器,可以是任何可編輯的組件。
setEditorData()提供編輯器的初始值,即雙擊編輯時(shí)初始顯示的內(nèi)容,通常都是編輯前該位置的內(nèi)容。
setModelData()當(dāng)輸入完畢后更改底層數(shù)據(jù),通過Model Index。將創(chuàng)建的組件中存儲(chǔ)的內(nèi)容取出,再利用model->setData()函數(shù)修改數(shù)據(jù)。
updateEditorGeometry()用于改變編輯器的位置和大小,將它放在需要編輯的位置。
委托對(duì)于輸入的控制主要是利用createEditor中使用的組件,比如如果在該函數(shù)中使用QSpinBox,那這個(gè)編輯器可能就只允許輸入整數(shù)。如果使用QLineEdit,那么可以輸入任何內(nèi)容。輸入完成之后,Delegate會(huì)發(fā)出信號(hào)告訴Model和View編輯完成,然后在setModelData函數(shù)中我們需要將創(chuàng)建的組件中存儲(chǔ)的信息取出,然后利用model->setData()函數(shù)來更新數(shù)據(jù)。當(dāng)數(shù)據(jù)發(fā)生改變后,Model又發(fā)出信號(hào)告訴View,隨后View會(huì)自動(dòng)更新顯示的內(nèi)容(這是Qt自動(dòng)完成的)。
總結(jié)
以上是生活随笔為你收集整理的Qt学习笔记-----Model/View架构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt学习笔记-----Graphics_
- 下一篇: Qt学习笔记-----Model/Vie