Qt入門(mén)教程第7章(3課時(shí))_第1頁(yè)
Qt入門(mén)教程第7章(3課時(shí))_第2頁(yè)
Qt入門(mén)教程第7章(3課時(shí))_第3頁(yè)
Qt入門(mén)教程第7章(3課時(shí))_第4頁(yè)
Qt入門(mén)教程第7章(3課時(shí))_第5頁(yè)
已閱讀5頁(yè),還剩61頁(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、Qt Creator快速入門(mén)快速入門(mén)第第2版版第第7 7章章 QtQt對(duì)象模型與容器類對(duì)象模型與容器類(3課時(shí))主主 要要 內(nèi)內(nèi) 容容n7.1 對(duì)象模型對(duì)象模型(第(第1課時(shí))課時(shí))n7.2 容器類(第容器類(第2課時(shí))課時(shí))n7.3 正則表達(dá)式(第正則表達(dá)式(第3課時(shí))課時(shí))n7.4 小結(jié)(第小結(jié)(第3課時(shí))課時(shí))7.1 對(duì)象模型對(duì)象模型 標(biāo)準(zhǔn)標(biāo)準(zhǔn)C+對(duì)象模型可以在運(yùn)行時(shí)非常有效的支持對(duì)象范式(對(duì)象模型可以在運(yùn)行時(shí)非常有效的支持對(duì)象范式(object paradigm),),但是它的靜態(tài)特性在一些問(wèn)題領(lǐng)域中不夠靈活。圖形用戶界面編程不僅需要運(yùn)行時(shí)但是它的靜態(tài)特性在一些問(wèn)題領(lǐng)域中不夠靈活。圖形

2、用戶界面編程不僅需要運(yùn)行時(shí)的高效性,還需要高度的靈活性。為此,的高效性,還需要高度的靈活性。為此,Qt在標(biāo)準(zhǔn)在標(biāo)準(zhǔn)C+對(duì)象模型的基礎(chǔ)上添加了一對(duì)象模型的基礎(chǔ)上添加了一些特性,形成了自己的對(duì)象模型。這些特性有:些特性,形成了自己的對(duì)象模型。這些特性有:n一個(gè)強(qiáng)大的無(wú)縫對(duì)象通信機(jī)制一個(gè)強(qiáng)大的無(wú)縫對(duì)象通信機(jī)制信號(hào)和槽信號(hào)和槽(signals and slots););n可查詢和可設(shè)計(jì)的對(duì)象可查詢和可設(shè)計(jì)的對(duì)象屬性系統(tǒng)屬性系統(tǒng)(object properties););n強(qiáng)大的事件和事件過(guò)濾器(強(qiáng)大的事件和事件過(guò)濾器(events and event filters););n通過(guò)上下文進(jìn)行國(guó)際化的字符

3、串翻譯機(jī)制(通過(guò)上下文進(jìn)行國(guó)際化的字符串翻譯機(jī)制(string translation for internationalization););n完善的定時(shí)器(完善的定時(shí)器(timers)驅(qū)動(dòng),使得可以在一個(gè)事件驅(qū)動(dòng)的)驅(qū)動(dòng),使得可以在一個(gè)事件驅(qū)動(dòng)的GUI中處理多個(gè)任務(wù);中處理多個(gè)任務(wù);n分層結(jié)構(gòu)的、可查詢的分層結(jié)構(gòu)的、可查詢的對(duì)象樹(shù)對(duì)象樹(shù)(object trees),它使用一種很自然的方式來(lái)組織),它使用一種很自然的方式來(lái)組織對(duì)象對(duì)象擁有權(quán)擁有權(quán)(object ownership););n守衛(wèi)指針即守衛(wèi)指針即QPointer,它在引用對(duì)象被銷毀時(shí)自動(dòng)將其設(shè)置為,它在引用對(duì)象被銷毀時(shí)自動(dòng)將其設(shè)

4、置為0;n動(dòng)態(tài)的對(duì)象轉(zhuǎn)換機(jī)制(動(dòng)態(tài)的對(duì)象轉(zhuǎn)換機(jī)制(dynamic cast);); Qt的這些特性都是在遵循標(biāo)準(zhǔn)的這些特性都是在遵循標(biāo)準(zhǔn)C+規(guī)范內(nèi)實(shí)現(xiàn)的,使用這些特性都必須要繼承自規(guī)范內(nèi)實(shí)現(xiàn)的,使用這些特性都必須要繼承自QObject類。其中對(duì)象通信機(jī)制和動(dòng)態(tài)屬性系統(tǒng),還需要類。其中對(duì)象通信機(jī)制和動(dòng)態(tài)屬性系統(tǒng),還需要元對(duì)象系統(tǒng)元對(duì)象系統(tǒng)(Meta-Object System)的支持。)的支持。 信號(hào)和槽信號(hào)和槽n信號(hào)和槽用于兩個(gè)對(duì)象之間的通信,信號(hào)和槽機(jī)制是信號(hào)和槽用于兩個(gè)對(duì)象之間的通信,信號(hào)和槽機(jī)制是Qt的核心特征,也是的核心特征,也是Qt不同于其他開(kāi)發(fā)框架的最突出的特征。在不同于其他開(kāi)發(fā)框

5、架的最突出的特征。在GUI編程中,當(dāng)改變了一個(gè)部件時(shí),編程中,當(dāng)改變了一個(gè)部件時(shí),總希望其他部件也能了解到該變化。更一般來(lái)說(shuō),我們希望任何對(duì)象都可以總希望其他部件也能了解到該變化。更一般來(lái)說(shuō),我們希望任何對(duì)象都可以和其他對(duì)象進(jìn)行通信。例如,如果用戶點(diǎn)擊了關(guān)閉按鈕,我們希望可以執(zhí)行和其他對(duì)象進(jìn)行通信。例如,如果用戶點(diǎn)擊了關(guān)閉按鈕,我們希望可以執(zhí)行窗口的窗口的close()函數(shù)來(lái)關(guān)閉窗口。為了實(shí)現(xiàn)對(duì)象間的通信,一些工具包中使用函數(shù)來(lái)關(guān)閉窗口。為了實(shí)現(xiàn)對(duì)象間的通信,一些工具包中使用了回調(diào)(了回調(diào)(callback)機(jī)制,而在)機(jī)制,而在Qt中,使用了信號(hào)和槽來(lái)進(jìn)行對(duì)象間的通信。中,使用了信號(hào)和槽來(lái)進(jìn)

6、行對(duì)象間的通信。當(dāng)一個(gè)特殊的事情發(fā)生時(shí)便可以發(fā)射一個(gè)信號(hào),比如按鈕被單擊;而槽就是當(dāng)一個(gè)特殊的事情發(fā)生時(shí)便可以發(fā)射一個(gè)信號(hào),比如按鈕被單擊;而槽就是一個(gè)函數(shù),它在信號(hào)發(fā)射后被調(diào)用,來(lái)響應(yīng)這個(gè)信號(hào)。在一個(gè)函數(shù),它在信號(hào)發(fā)射后被調(diào)用,來(lái)響應(yīng)這個(gè)信號(hào)。在Qt的部件類中已經(jīng)的部件類中已經(jīng)定義了一些信號(hào)和槽,但是更多的做法是子類化這個(gè)部件,然后添加自己的定義了一些信號(hào)和槽,但是更多的做法是子類化這個(gè)部件,然后添加自己的信號(hào)和槽來(lái)實(shí)現(xiàn)想要的功能。信號(hào)和槽來(lái)實(shí)現(xiàn)想要的功能。 n一個(gè)信號(hào)可以關(guān)聯(lián)到多個(gè)槽上,多個(gè)信號(hào)也可以關(guān)聯(lián)到同一個(gè)槽上,甚至,一個(gè)信號(hào)可以關(guān)聯(lián)到多個(gè)槽上,多個(gè)信號(hào)也可以關(guān)聯(lián)到同一個(gè)槽上,甚至,

7、一個(gè)信號(hào)還可以關(guān)聯(lián)到另一個(gè)信號(hào)上。如果存在多個(gè)槽與某個(gè)信號(hào)相關(guān)聯(lián),一個(gè)信號(hào)還可以關(guān)聯(lián)到另一個(gè)信號(hào)上。如果存在多個(gè)槽與某個(gè)信號(hào)相關(guān)聯(lián),那么,當(dāng)這個(gè)信號(hào)被發(fā)射時(shí),這些槽將會(huì)一個(gè)接一個(gè)地執(zhí)行,但是它們執(zhí)行那么,當(dāng)這個(gè)信號(hào)被發(fā)射時(shí),這些槽將會(huì)一個(gè)接一個(gè)地執(zhí)行,但是它們執(zhí)行的順序是隨機(jī)的,無(wú)法指定它們的執(zhí)行順序。的順序是隨機(jī)的,無(wú)法指定它們的執(zhí)行順序。 信號(hào)信號(hào)聲明一個(gè)信號(hào),例如:聲明一個(gè)信號(hào),例如:signals: void dlgReturn(int); / 自定義的信號(hào)自定義的信號(hào)n聲明一個(gè)信號(hào)要使用聲明一個(gè)信號(hào)要使用signals關(guān)鍵字。關(guān)鍵字。n在在signals前面不能使用前面不能使用pub

8、lic、private和和protected等限定符,因?yàn)榈认薅ǚ驗(yàn)橹挥卸x該信號(hào)的類及其子類才可以發(fā)射該信號(hào)。只有定義該信號(hào)的類及其子類才可以發(fā)射該信號(hào)。n信號(hào)只用聲明,不需要也不能對(duì)它進(jìn)行定義實(shí)現(xiàn)。信號(hào)只用聲明,不需要也不能對(duì)它進(jìn)行定義實(shí)現(xiàn)。n信號(hào)沒(méi)有返回值,只能是信號(hào)沒(méi)有返回值,只能是void類型的。類型的。n只有只有QObject類及其子類派生的類才能使用信號(hào)和槽機(jī)制,使用信號(hào)類及其子類派生的類才能使用信號(hào)和槽機(jī)制,使用信號(hào)和槽,還必須在類聲明的最開(kāi)始處添加和槽,還必須在類聲明的最開(kāi)始處添加Q_OBJECT宏。宏。發(fā)射信號(hào)發(fā)射信號(hào)例如:例如:void MyDialog:on_pus

9、hButton_clicked() / 確定按鈕確定按鈕 int value = ui-spinBox-value(); / 獲取輸入的數(shù)值獲取輸入的數(shù)值 emit dlgReturn(value); / 發(fā)射信號(hào)發(fā)射信號(hào) close(); / 關(guān)閉對(duì)話框關(guān)閉對(duì)話框當(dāng)單擊確定按鈕時(shí),便獲取當(dāng)單擊確定按鈕時(shí),便獲取spinBox部件中的數(shù)值,然后使用自定義部件中的數(shù)值,然后使用自定義的信號(hào)將其作為參數(shù)發(fā)射出去。發(fā)射一個(gè)信號(hào)要使用的信號(hào)將其作為參數(shù)發(fā)射出去。發(fā)射一個(gè)信號(hào)要使用emit關(guān)鍵字,例關(guān)鍵字,例如程序中發(fā)射了如程序中發(fā)射了dlgReturn()信號(hào)。信號(hào)。槽槽自定義槽的聲明:自定義槽的聲明

10、:private slots: void showValue(int value);實(shí)現(xiàn):實(shí)現(xiàn):nvoid Widget:showValue(int value) / 自定義槽自定義槽nn ui-label-setText(tr(獲取的值是:獲取的值是:%1).arg(value);n聲明一個(gè)槽需要使用聲明一個(gè)槽需要使用slots關(guān)鍵字。一個(gè)槽可以是關(guān)鍵字。一個(gè)槽可以是private、public或者或者protected類型的,槽也可以被聲明為虛函數(shù),這與普通的成員函數(shù)是一樣類型的,槽也可以被聲明為虛函數(shù),這與普通的成員函數(shù)是一樣的,也可以像調(diào)用一個(gè)普通函數(shù)一樣來(lái)調(diào)用槽。槽的最大特點(diǎn)就是可以

11、和信的,也可以像調(diào)用一個(gè)普通函數(shù)一樣來(lái)調(diào)用槽。槽的最大特點(diǎn)就是可以和信號(hào)關(guān)聯(lián)。號(hào)關(guān)聯(lián)。信號(hào)和槽的關(guān)聯(lián)信號(hào)和槽的關(guān)聯(lián)例如:例如:MyDialog *dlg = new MyDialog(this); connect(dlg,SIGNAL(dlgReturn(int),this,SLOT(showValue(int);connect()函數(shù)原型如下:函數(shù)原型如下:bool QObject:connect ( const QObject * sender, const char * signal, const QObject * receiver, const char * method, Qt:C

12、onnectionType type = Qt:AutoConnection )n它的第一個(gè)參數(shù)為發(fā)送信號(hào)的對(duì)象,例如這里的它的第一個(gè)參數(shù)為發(fā)送信號(hào)的對(duì)象,例如這里的dlg;n第二個(gè)參數(shù)是要發(fā)送的信號(hào),這里是第二個(gè)參數(shù)是要發(fā)送的信號(hào),這里是SIGNAL(dlgReturn(int);n第三個(gè)參數(shù)是接收信號(hào)的對(duì)象,這里是第三個(gè)參數(shù)是接收信號(hào)的對(duì)象,這里是this,表明是本部件,即,表明是本部件,即Widget,當(dāng)這個(gè)參數(shù)為,當(dāng)這個(gè)參數(shù)為this時(shí),也時(shí),也可以將這個(gè)參數(shù)省略掉,因?yàn)榭梢詫⑦@個(gè)參數(shù)省略掉,因?yàn)閏onnect()函數(shù)還有另外一個(gè)重載形式,該參數(shù)默認(rèn)為函數(shù)還有另外一個(gè)重載形式,該參數(shù)默

13、認(rèn)為this;n第四個(gè)參數(shù)是要執(zhí)行的槽,這里是第四個(gè)參數(shù)是要執(zhí)行的槽,這里是SLOT(showValue(int)。n對(duì)于信號(hào)和槽,必須使用對(duì)于信號(hào)和槽,必須使用SIGNAL()和和SLOT()宏,它們可以將其參數(shù)轉(zhuǎn)化為宏,它們可以將其參數(shù)轉(zhuǎn)化為const char* 類型。類型。connect()函數(shù)的返回值為函數(shù)的返回值為bool類型,當(dāng)關(guān)聯(lián)成功時(shí)返回類型,當(dāng)關(guān)聯(lián)成功時(shí)返回true。n信號(hào)和槽的參數(shù)只能有類型,不能有變量,例如寫(xiě)成信號(hào)和槽的參數(shù)只能有類型,不能有變量,例如寫(xiě)成SLOT(showValue(int value)是不對(duì)的。對(duì)是不對(duì)的。對(duì)于信號(hào)和槽的參數(shù)問(wèn)題,基本原則是信號(hào)中的參

14、數(shù)類型要和槽中的參數(shù)類型相對(duì)應(yīng),而且信號(hào)中于信號(hào)和槽的參數(shù)問(wèn)題,基本原則是信號(hào)中的參數(shù)類型要和槽中的參數(shù)類型相對(duì)應(yīng),而且信號(hào)中的參數(shù)可以多于槽中的參數(shù),但是不能反過(guò)來(lái),如果信號(hào)中有多余的參數(shù),那么它們將被忽略。的參數(shù)可以多于槽中的參數(shù),但是不能反過(guò)來(lái),如果信號(hào)中有多余的參數(shù),那么它們將被忽略。 關(guān)聯(lián)方式關(guān)聯(lián)方式 connect()函數(shù)的最后一個(gè)參數(shù),它表明了關(guān)聯(lián)的方式,其默認(rèn)值是函數(shù)的最后一個(gè)參數(shù),它表明了關(guān)聯(lián)的方式,其默認(rèn)值是Qt:AutoConnection,這里還有其他幾個(gè)選擇,具體功能如下表所示,這里還有其他幾個(gè)選擇,具體功能如下表所示 。使用信號(hào)和槽注意事項(xiàng)使用信號(hào)和槽注意事項(xiàng)n需要

15、繼承自需要繼承自QObject或其子類;或其子類;n在類聲明的最開(kāi)始處添加在類聲明的最開(kāi)始處添加Q_OBJECT宏;宏;n槽中的參數(shù)的類型要和信號(hào)的參數(shù)的類型相對(duì)應(yīng),且不能槽中的參數(shù)的類型要和信號(hào)的參數(shù)的類型相對(duì)應(yīng),且不能比信號(hào)的參數(shù)多;比信號(hào)的參數(shù)多;n信號(hào)只用聲明,沒(méi)有定義,且返回值為信號(hào)只用聲明,沒(méi)有定義,且返回值為void類型。類型。信號(hào)和槽自動(dòng)關(guān)聯(lián)信號(hào)和槽自動(dòng)關(guān)聯(lián) 信號(hào)和槽還有一種自動(dòng)關(guān)聯(lián)方式,比如在設(shè)計(jì)模式直接生成的信號(hào)和槽還有一種自動(dòng)關(guān)聯(lián)方式,比如在設(shè)計(jì)模式直接生成的“確定確定”按鈕的單擊信號(hào)的槽,就是使用的這種方式:按鈕的單擊信號(hào)的槽,就是使用的這種方式: on_pushBut

16、ton_clicked() 它由它由“on”、部件的、部件的objectName和信號(hào)三部分組成,中間用下劃線和信號(hào)三部分組成,中間用下劃線隔開(kāi)。這樣組織的名稱的槽就可以直接和信號(hào)關(guān)聯(lián),而不用再使用隔開(kāi)。這樣組織的名稱的槽就可以直接和信號(hào)關(guān)聯(lián),而不用再使用connect()函數(shù)。函數(shù)。 自學(xué):自學(xué):如果不使用設(shè)計(jì)模式生成,自定義的信號(hào)和槽應(yīng)該如何使用自動(dòng)關(guān)聯(lián),如果不使用設(shè)計(jì)模式生成,自定義的信號(hào)和槽應(yīng)該如何使用自動(dòng)關(guān)聯(lián),需要注意哪些事項(xiàng)?需要注意哪些事項(xiàng)?信號(hào)和槽的高級(jí)應(yīng)用信號(hào)和槽的高級(jí)應(yīng)用n有時(shí)希望獲得信號(hào)發(fā)送者的信息,在有時(shí)希望獲得信號(hào)發(fā)送者的信息,在Qt中提供了中提供了QObject:s

17、ender()函數(shù)來(lái)返回發(fā)送該信號(hào)的對(duì)象的指針。函數(shù)來(lái)返回發(fā)送該信號(hào)的對(duì)象的指針。n但是如果有多個(gè)信號(hào)關(guān)聯(lián)到了同一個(gè)槽上,而在該槽中需但是如果有多個(gè)信號(hào)關(guān)聯(lián)到了同一個(gè)槽上,而在該槽中需要對(duì)每一個(gè)信號(hào)進(jìn)行不同的處理,使用上面的方法就很麻要對(duì)每一個(gè)信號(hào)進(jìn)行不同的處理,使用上面的方法就很麻煩了。對(duì)于這種情況,便可以使用煩了。對(duì)于這種情況,便可以使用QSignalMapper類。類。QSignalMapper可以被叫做信號(hào)映射器,它可以實(shí)現(xiàn)對(duì)可以被叫做信號(hào)映射器,它可以實(shí)現(xiàn)對(duì)多個(gè)相同部件的相同信號(hào)進(jìn)行映射,為其添加字符串或者多個(gè)相同部件的相同信號(hào)進(jìn)行映射,為其添加字符串或者數(shù)值參數(shù),然后再發(fā)射出去。數(shù)

18、值參數(shù),然后再發(fā)射出去。 信號(hào)和槽機(jī)制的特色和優(yōu)越性信號(hào)和槽機(jī)制的特色和優(yōu)越性信號(hào)和槽機(jī)制的特色和優(yōu)越性:信號(hào)和槽機(jī)制的特色和優(yōu)越性:n信號(hào)和槽機(jī)制是類型安全的,相關(guān)聯(lián)的信號(hào)和槽的參數(shù)必須匹配;信號(hào)和槽機(jī)制是類型安全的,相關(guān)聯(lián)的信號(hào)和槽的參數(shù)必須匹配;n信號(hào)和槽是松耦合的,信號(hào)發(fā)送者不知道也不需要知道接受者的信息;信號(hào)和槽是松耦合的,信號(hào)發(fā)送者不知道也不需要知道接受者的信息;n信號(hào)和槽可以使用任意類型的任意數(shù)量的參數(shù)。信號(hào)和槽可以使用任意類型的任意數(shù)量的參數(shù)。 雖然信號(hào)和槽機(jī)制提供了高度的靈活性,但就其性能而言,還是慢于雖然信號(hào)和槽機(jī)制提供了高度的靈活性,但就其性能而言,還是慢于回調(diào)機(jī)制的。當(dāng)

19、然,這點(diǎn)性能差異通常在一個(gè)應(yīng)用程序中是很難體現(xiàn)回調(diào)機(jī)制的。當(dāng)然,這點(diǎn)性能差異通常在一個(gè)應(yīng)用程序中是很難體現(xiàn)出來(lái)的。出來(lái)的。屬性系統(tǒng)屬性系統(tǒng) Qt提供了強(qiáng)大的基于元對(duì)象系統(tǒng)的屬性系統(tǒng),可以在能夠運(yùn)行提供了強(qiáng)大的基于元對(duì)象系統(tǒng)的屬性系統(tǒng),可以在能夠運(yùn)行Qt的平臺(tái)上支持任意的標(biāo)準(zhǔn)的平臺(tái)上支持任意的標(biāo)準(zhǔn)C+編譯器。要聲明一個(gè)屬性,那么該類必須繼承自編譯器。要聲明一個(gè)屬性,那么該類必須繼承自QObject類,而且還要在聲明前使用類,而且還要在聲明前使用Q_PROPERTY()宏:宏:Q_PROPERTY(type name READ getFunction WRITE setFunction RESET

20、 resetFunction NOTIFY notifySignal DESIGNABLE bool SCRIPTABLE bool STORED bool USER bool CONSTANT FINAL) 其中其中type表示屬性的類型,它可以是表示屬性的類型,它可以是QVariant所支持的類型或者是用戶自定義的類型。而如所支持的類型或者是用戶自定義的類型。而如果是枚舉類型,還需要使用果是枚舉類型,還需要使用Q_ENUMS()宏在元對(duì)象系統(tǒng)中進(jìn)行注冊(cè),這樣以后才可以使用宏在元對(duì)象系統(tǒng)中進(jìn)行注冊(cè),這樣以后才可以使用QObject:setProperty()函數(shù)來(lái)使用該屬性。函數(shù)來(lái)使用該屬性

21、。name就是屬性的名稱。就是屬性的名稱。READ后面是讀取該屬后面是讀取該屬性的函數(shù),這個(gè)函數(shù)是必須有的,而后面帶有性的函數(shù),這個(gè)函數(shù)是必須有的,而后面帶有“ ”號(hào)的選項(xiàng)表示這些函數(shù)是可選的。號(hào)的選項(xiàng)表示這些函數(shù)是可選的。 一個(gè)屬性類似于一個(gè)數(shù)據(jù)成員,不過(guò)添加了一些可以通過(guò)元對(duì)象系統(tǒng)訪問(wèn)的附加功能:一個(gè)屬性類似于一個(gè)數(shù)據(jù)成員,不過(guò)添加了一些可以通過(guò)元對(duì)象系統(tǒng)訪問(wèn)的附加功能:n一個(gè)讀(一個(gè)讀(READ)訪問(wèn)函數(shù)。該函數(shù)是必須有的,它用來(lái)讀取屬性的取值。這個(gè)函數(shù))訪問(wèn)函數(shù)。該函數(shù)是必須有的,它用來(lái)讀取屬性的取值。這個(gè)函數(shù)一般是一般是const類型的,它的返回值類型必須是該屬性的類型,或者是該屬性

22、類型的指類型的,它的返回值類型必須是該屬性的類型,或者是該屬性類型的指針或者引用;針或者引用;n一個(gè)可選的寫(xiě)(一個(gè)可選的寫(xiě)(WRITE)訪問(wèn)函數(shù)。它用來(lái)設(shè)置屬性的值。這個(gè)函數(shù)必須只有一個(gè))訪問(wèn)函數(shù)。它用來(lái)設(shè)置屬性的值。這個(gè)函數(shù)必須只有一個(gè)參數(shù),而且它的返回值必須為空參數(shù),而且它的返回值必須為空void;n一個(gè)可選的重置(一個(gè)可選的重置(RESET)函數(shù)。它用來(lái)將屬性恢復(fù)到一個(gè)默認(rèn)的值。這個(gè)函數(shù)不)函數(shù)。它用來(lái)將屬性恢復(fù)到一個(gè)默認(rèn)的值。這個(gè)函數(shù)不能有參數(shù),而且返回值必須為空能有參數(shù),而且返回值必須為空void;n一個(gè)可選的通知(一個(gè)可選的通知(NOTIFY)信號(hào)。如果使用該選項(xiàng),那么每當(dāng)屬性的值

23、改變時(shí)都要)信號(hào)。如果使用該選項(xiàng),那么每當(dāng)屬性的值改變時(shí)都要發(fā)射一個(gè)指定的信號(hào);發(fā)射一個(gè)指定的信號(hào);n可選的可選的DESIGNABLE表明這個(gè)屬性在表明這個(gè)屬性在GUI設(shè)計(jì)器(例如設(shè)計(jì)器(例如Qt Designer)的屬性編輯)的屬性編輯器中是否可見(jiàn)。大多數(shù)屬性的該值為器中是否可見(jiàn)。大多數(shù)屬性的該值為true,即可見(jiàn);,即可見(jiàn);n可選的可選的SCRIPTABLE表明這個(gè)屬性是否可以被腳本引擎(表明這個(gè)屬性是否可以被腳本引擎(scripting engine)訪問(wèn),)訪問(wèn),默認(rèn)值為默認(rèn)值為true;n可選的可選的STORED表明是否在當(dāng)對(duì)象的狀態(tài)被存儲(chǔ)時(shí)也必須存儲(chǔ)這個(gè)屬性的值,大部表明是否在當(dāng)對(duì)

24、象的狀態(tài)被存儲(chǔ)時(shí)也必須存儲(chǔ)這個(gè)屬性的值,大部分屬性的該值為分屬性的該值為true;n可選的可選的USER表明這個(gè)屬性是否被設(shè)計(jì)為該類的面向用戶或者用戶可編輯的屬性。一表明這個(gè)屬性是否被設(shè)計(jì)為該類的面向用戶或者用戶可編輯的屬性。一般,每一個(gè)類中只有一個(gè)般,每一個(gè)類中只有一個(gè)USER屬性,它的默認(rèn)值為屬性,它的默認(rèn)值為false;n可選的可選的CONSTANT表明這個(gè)屬性的值是一個(gè)常量。對(duì)于給定的一個(gè)對(duì)象實(shí)例,每一表明這個(gè)屬性的值是一個(gè)常量。對(duì)于給定的一個(gè)對(duì)象實(shí)例,每一次使用常量屬性的次使用常量屬性的READ方法都必須返回相同的值,但對(duì)于不同的實(shí)例,這個(gè)常量可方法都必須返回相同的值,但對(duì)于不同的實(shí)

25、例,這個(gè)常量可以不同。一個(gè)常量屬性不可以有以不同。一個(gè)常量屬性不可以有WRITE方法和方法和NOTIFY信號(hào);信號(hào);n可選的可選的FINAL表明這個(gè)屬性不能被派生類重寫(xiě)。表明這個(gè)屬性不能被派生類重寫(xiě)。 其中的其中的READ,WRITE和和RESET函數(shù)可以被繼承,也可以是虛的(函數(shù)可以被繼承,也可以是虛的(virtual),當(dāng)在),當(dāng)在多繼承時(shí),它們必須繼承自第一個(gè)父類。多繼承時(shí),它們必須繼承自第一個(gè)父類。 自定義屬性示例自定義屬性示例class MyClass : public QObject Q_OBJECT Q_PROPERTY(QString userName READ getUser

26、Name WRITE setUserName NOTIFY userNameChanged); / 注冊(cè)屬性注冊(cè)屬性u(píng)serNamepublic: explicit MyClass(QObject *parent = 0); QString getUserName() const / 實(shí)現(xiàn)實(shí)現(xiàn)READ讀函數(shù)讀函數(shù) return m_userName; void setUserName(QString userName) / 實(shí)現(xiàn)實(shí)現(xiàn)WRITE寫(xiě)函數(shù)寫(xiě)函數(shù) m_userName = userName; emit userNameChanged(userName); / 當(dāng)屬性值改變時(shí)發(fā)射該信號(hào)當(dāng)

27、屬性值改變時(shí)發(fā)射該信號(hào) signals: void userNameChanged(QString); / 聲明聲明NOTIFY通知消息通知消息private: QString m_userName; / 私有變量,存放私有變量,存放userName屬性的值屬性的值;使用自定義的屬性:使用自定義的屬性: MyClass *my = new MyClass(this); / 創(chuàng)建創(chuàng)建MyClass類實(shí)例類實(shí)例 connect(my,SIGNAL(userNameChanged(QString),this, SLOT(userChanged(QString);my-setUserName(“yaf

28、ei”); / 設(shè)置屬性的值設(shè)置屬性的值qDebug() “userName:” getUserName(); / 輸出屬性的值輸出屬性的值/ 使用使用QObject類的類的setProperty()函數(shù)設(shè)置屬性的值函數(shù)設(shè)置屬性的值my-setProperty(userName,linux); / 輸出屬性的值,這里使用了輸出屬性的值,這里使用了QObject類的類的property()函數(shù),它返回值類型為函數(shù),它返回值類型為QVariantqDebug() userName: property(userName).toString(); 對(duì)象樹(shù)和擁有權(quán)對(duì)象樹(shù)和擁有權(quán) Qt中使用對(duì)象樹(shù)(中使用

29、對(duì)象樹(shù)(object tree)來(lái)組織和管理所有的)來(lái)組織和管理所有的QObject類及其子類及其子類的對(duì)象。當(dāng)創(chuàng)建一個(gè)類的對(duì)象。當(dāng)創(chuàng)建一個(gè)QObject時(shí),如果使用了其他的對(duì)象作為其父對(duì)象時(shí),如果使用了其他的對(duì)象作為其父對(duì)象(parent),那么這個(gè)),那么這個(gè)QObject就會(huì)被添加到父對(duì)象的就會(huì)被添加到父對(duì)象的children()列表中,這列表中,這樣當(dāng)父對(duì)象被銷毀時(shí),這個(gè)樣當(dāng)父對(duì)象被銷毀時(shí),這個(gè)QObject也會(huì)被銷毀。實(shí)踐表明,這個(gè)機(jī)制非常也會(huì)被銷毀。實(shí)踐表明,這個(gè)機(jī)制非常適合于管理適合于管理GUI對(duì)象。例如,一個(gè)對(duì)象。例如,一個(gè)QShortcut(鍵盤(pán)快捷鍵)對(duì)象是相應(yīng)窗(鍵盤(pán)快捷

30、鍵)對(duì)象是相應(yīng)窗口的一個(gè)子對(duì)象,所以當(dāng)用戶關(guān)閉了這個(gè)窗口時(shí),這個(gè)快捷鍵也可以被銷毀??诘囊粋€(gè)子對(duì)象,所以當(dāng)用戶關(guān)閉了這個(gè)窗口時(shí),這個(gè)快捷鍵也可以被銷毀。 QWidget作為能夠在屏幕上顯示的所有部件的基類,擴(kuò)展了對(duì)象間的父作為能夠在屏幕上顯示的所有部件的基類,擴(kuò)展了對(duì)象間的父子關(guān)系。一個(gè)子對(duì)象一般也就是一個(gè)子部件,因?yàn)樗鼈円@示在父部件的區(qū)子關(guān)系。一個(gè)子對(duì)象一般也就是一個(gè)子部件,因?yàn)樗鼈円@示在父部件的區(qū)域之中。例如,當(dāng)關(guān)閉一個(gè)消息對(duì)話框(域之中。例如,當(dāng)關(guān)閉一個(gè)消息對(duì)話框(message box)后要銷毀它時(shí),消)后要銷毀它時(shí),消息對(duì)話框中的按鈕和標(biāo)簽也會(huì)被銷毀,這也正是我們所希望的,因?yàn)榘?/p>

31、鈕和息對(duì)話框中的按鈕和標(biāo)簽也會(huì)被銷毀,這也正是我們所希望的,因?yàn)榘粹o和標(biāo)簽是消息對(duì)話框的子部件。當(dāng)然,也可以自己來(lái)銷毀一個(gè)子對(duì)象。標(biāo)簽是消息對(duì)話框的子部件。當(dāng)然,也可以自己來(lái)銷毀一個(gè)子對(duì)象。 示例示例n自定義繼承自自定義繼承自QPushButton的的MyButton 類,添加析構(gòu)函數(shù)的聲明:類,添加析構(gòu)函數(shù)的聲明:MyButton();n定義析構(gòu)函數(shù):定義析構(gòu)函數(shù):MyButton:MyButton() qDebug() setText(tr(button);n更改更改Widget類的析構(gòu)函數(shù):類的析構(gòu)函數(shù):Widget:Widget() delete ui; qDebug() delete

32、 widget; 當(dāng)當(dāng)Widget窗口被銷毀時(shí),將輸出信息。窗口被銷毀時(shí),將輸出信息。 運(yùn)行程序,然后關(guān)閉窗口,在運(yùn)行程序,然后關(guān)閉窗口,在Qt Creator的應(yīng)用程序輸出欄中的輸出信息為:的應(yīng)用程序輸出欄中的輸出信息為:delete widget delete button可以看到,當(dāng)關(guān)閉窗口后,因?yàn)樵摯翱谑琼攲哟翱冢詰?yīng)用程序要銷毀該窗口部件可以看到,當(dāng)關(guān)閉窗口后,因?yàn)樵摯翱谑琼攲哟翱?,所以?yīng)用程序要銷毀該窗口部件(如果不是頂層窗口,那么關(guān)閉時(shí)只是隱藏,不會(huì)被銷毀),而當(dāng)窗口部件銷毀時(shí)會(huì)(如果不是頂層窗口,那么關(guān)閉時(shí)只是隱藏,不會(huì)被銷毀),而當(dāng)窗口部件銷毀時(shí)會(huì)自動(dòng)銷毀其子部件。這也就是

33、為什么自動(dòng)銷毀其子部件。這也就是為什么在在Qt中經(jīng)常只看到中經(jīng)常只看到new操作而看不到操作而看不到delete操作操作的原因。的原因。 在在main.cpp文件,其中文件,其中Widget對(duì)象是建立在棧上的:對(duì)象是建立在棧上的:Widget w;w.show();這樣對(duì)于對(duì)象這樣對(duì)于對(duì)象w,在關(guān)閉程序時(shí)會(huì)被自動(dòng)銷毀。而對(duì)于,在關(guān)閉程序時(shí)會(huì)被自動(dòng)銷毀。而對(duì)于Widget中的部件,如果是在堆中的部件,如果是在堆上創(chuàng)建(使用上創(chuàng)建(使用new操作符),那么只要指定操作符),那么只要指定Widget為其父窗口就可以了,也不需要進(jìn)為其父窗口就可以了,也不需要進(jìn)行行delete操作。整個(gè)應(yīng)用程序關(guān)閉時(shí),

34、會(huì)去銷毀操作。整個(gè)應(yīng)用程序關(guān)閉時(shí),會(huì)去銷毀w對(duì)象,而此時(shí)又會(huì)自動(dòng)銷毀它的所對(duì)象,而此時(shí)又會(huì)自動(dòng)銷毀它的所有子部件,這些都是有子部件,這些都是Qt的對(duì)象樹(shù)所完成的。的對(duì)象樹(shù)所完成的。所以,對(duì)于規(guī)范的所以,對(duì)于規(guī)范的Qt程序,要在程序,要在main()函數(shù)中將主窗口部件創(chuàng)建在棧上,例如函數(shù)中將主窗口部件創(chuàng)建在棧上,例如“Widget w;”,而不要在堆上進(jìn)行創(chuàng)建(使用,而不要在堆上進(jìn)行創(chuàng)建(使用new操作符)。對(duì)于其他窗口部件,可操作符)。對(duì)于其他窗口部件,可以使用以使用new操作符在堆上進(jìn)行創(chuàng)建,不過(guò)一定要指定其父部件,這樣就不需要再使用操作符在堆上進(jìn)行創(chuàng)建,不過(guò)一定要指定其父部件,這樣就不需要

35、再使用delete操作符來(lái)銷毀該對(duì)象了。操作符來(lái)銷毀該對(duì)象了。元對(duì)象系統(tǒng)元對(duì)象系統(tǒng) Qt中的元對(duì)象系統(tǒng)(中的元對(duì)象系統(tǒng)(Meta-Object System)提供了對(duì)象間通信的信)提供了對(duì)象間通信的信號(hào)和槽機(jī)制、運(yùn)行時(shí)類型信息和動(dòng)態(tài)屬性系統(tǒng)。元對(duì)象系統(tǒng)是基于以號(hào)和槽機(jī)制、運(yùn)行時(shí)類型信息和動(dòng)態(tài)屬性系統(tǒng)。元對(duì)象系統(tǒng)是基于以下三個(gè)條件的:下三個(gè)條件的:n該類必須繼承自該類必須繼承自QObject類;類;n必須在類的私有聲明區(qū)聲明必須在類的私有聲明區(qū)聲明Q_OBJECT宏(在類定義時(shí),如果沒(méi)有宏(在類定義時(shí),如果沒(méi)有指定指定public或者或者private,則默認(rèn)為,則默認(rèn)為private););n

36、元對(duì)象編譯器元對(duì)象編譯器Meta-Object Compiler(moc),為),為QObject的子類的子類實(shí)現(xiàn)元對(duì)象特性提供必要的代碼。實(shí)現(xiàn)元對(duì)象特性提供必要的代碼。 其中其中moc工具讀取一個(gè)工具讀取一個(gè)C+源文件,如果它發(fā)現(xiàn)一個(gè)或者多個(gè)類源文件,如果它發(fā)現(xiàn)一個(gè)或者多個(gè)類的聲明中包含有的聲明中包含有Q_OBJECT宏,便會(huì)另外創(chuàng)建一個(gè)宏,便會(huì)另外創(chuàng)建一個(gè)C+源文件(就源文件(就是在項(xiàng)目目錄中的是在項(xiàng)目目錄中的debug目錄下看到的以目錄下看到的以moc開(kāi)頭的開(kāi)頭的C+源文件),源文件),其中包含了為每一個(gè)類生成的元對(duì)象代碼。這些產(chǎn)生的源文件或者被其中包含了為每一個(gè)類生成的元對(duì)象代碼。這些

37、產(chǎn)生的源文件或者被包含進(jìn)類的源文件中,或者和類的實(shí)現(xiàn)同時(shí)進(jìn)行編譯和鏈接。包含進(jìn)類的源文件中,或者和類的實(shí)現(xiàn)同時(shí)進(jìn)行編譯和鏈接。 元對(duì)象系統(tǒng)主要是為了實(shí)現(xiàn)信號(hào)和槽機(jī)制才被引入的,不過(guò)除了信號(hào)元對(duì)象系統(tǒng)主要是為了實(shí)現(xiàn)信號(hào)和槽機(jī)制才被引入的,不過(guò)除了信號(hào)和槽機(jī)制以外,元對(duì)象系統(tǒng)還提供了其他一些特性:和槽機(jī)制以外,元對(duì)象系統(tǒng)還提供了其他一些特性:nQObject:metaObject()函數(shù)可以返回一個(gè)類的元對(duì)象,它是函數(shù)可以返回一個(gè)類的元對(duì)象,它是QMetaObject類的對(duì)象;類的對(duì)象;nQMetaObject:className()可以在運(yùn)行時(shí)以字符串形式返回類名,可以在運(yùn)行時(shí)以字符串形式返回類

38、名,而不需要而不需要C+編輯器原生的運(yùn)行時(shí)類型信息(編輯器原生的運(yùn)行時(shí)類型信息(RTTI)的支持;)的支持;nQObject:inherits()函數(shù)返回一個(gè)對(duì)象是否是函數(shù)返回一個(gè)對(duì)象是否是QObject繼承樹(shù)上一個(gè)繼承樹(shù)上一個(gè)類的實(shí)例的信息;類的實(shí)例的信息;nQObject:tr()和和QObject:trUtf8()進(jìn)行字符串翻譯來(lái)實(shí)現(xiàn)國(guó)際化;進(jìn)行字符串翻譯來(lái)實(shí)現(xiàn)國(guó)際化;nQObject:setProperty()和和QObject:property()通過(guò)名字來(lái)動(dòng)態(tài)設(shè)置通過(guò)名字來(lái)動(dòng)態(tài)設(shè)置或者獲取對(duì)象屬性;或者獲取對(duì)象屬性;nQMetaObject:newInstance()構(gòu)造該類的一個(gè)

39、新實(shí)例。構(gòu)造該類的一個(gè)新實(shí)例。7.2 容器類容器類 Qt庫(kù)提供了一組通用的基于模板的容器類(庫(kù)提供了一組通用的基于模板的容器類(container classes)。這些)。這些容器類可以用來(lái)存儲(chǔ)指定類型的項(xiàng)目(容器類可以用來(lái)存儲(chǔ)指定類型的項(xiàng)目(items),例如,如果大家需要一),例如,如果大家需要一個(gè)個(gè)QString類型的可變大小的數(shù)組,那么可以使用類型的可變大小的數(shù)組,那么可以使用QVector(QString)。與與STL(Standard Template Library,C+的標(biāo)準(zhǔn)模板庫(kù)的標(biāo)準(zhǔn)模板庫(kù))中的容器類相中的容器類相比,比,Qt中的這些容器類更輕量,更安全,更容易使用。中的

40、這些容器類更輕量,更安全,更容易使用。 nQt的容器類簡(jiǎn)介的容器類簡(jiǎn)介n遍歷容器遍歷容器n通用算法通用算法nQStringnQByteArray和和QVariantQt的容器類簡(jiǎn)介的容器類簡(jiǎn)介nQt提供了一些順序容器:提供了一些順序容器:QList,QLinkedList,QVector,QStack和和QQueue。因?yàn)檫@些容器中的數(shù)據(jù)都是一個(gè)接一個(gè)線性存儲(chǔ)的,所。因?yàn)檫@些容器中的數(shù)據(jù)都是一個(gè)接一個(gè)線性存儲(chǔ)的,所以稱為順序容器。對(duì)于大多數(shù)應(yīng)用程序而言,使用最多的,而且最好以稱為順序容器。對(duì)于大多數(shù)應(yīng)用程序而言,使用最多的,而且最好用的是用的是QList,雖然它是作為一個(gè)數(shù)組列表,但是它在頭部

41、和尾部進(jìn),雖然它是作為一個(gè)數(shù)組列表,但是它在頭部和尾部進(jìn)行添加操作是很快速的。如果需要使用一個(gè)鏈表,那么可以使用行添加操作是很快速的。如果需要使用一個(gè)鏈表,那么可以使用QLinkedList;如果希望數(shù)據(jù)項(xiàng)可以占用連續(xù)的內(nèi)存空間,可以使用;如果希望數(shù)據(jù)項(xiàng)可以占用連續(xù)的內(nèi)存空間,可以使用QVector。而。而QStack和和QQueue作為便捷類,分別提供了后進(jìn)先出作為便捷類,分別提供了后進(jìn)先出(LIFO)和先進(jìn)先出()和先進(jìn)先出(FIFO)語(yǔ)義。)語(yǔ)義。nQt還提供了一些關(guān)聯(lián)容器:還提供了一些關(guān)聯(lián)容器:QMap,QMultiMap,QHash,QMultiHash和和QSet。因?yàn)檫@些容器存儲(chǔ)

42、的是。因?yàn)檫@些容器存儲(chǔ)的是對(duì),比如對(duì),比如QMap,所以稱為關(guān)聯(lián)容器。其中,所以稱為關(guān)聯(lián)容器。其中“Multi”容器用來(lái)方便支容器用來(lái)方便支持一個(gè)鍵多個(gè)值的情況。持一個(gè)鍵多個(gè)值的情況。 QList是一個(gè)模板類,它提供了一個(gè)列表。是一個(gè)模板類,它提供了一個(gè)列表。QList實(shí)際上是一個(gè)實(shí)際上是一個(gè)T類型項(xiàng)目的指針數(shù)類型項(xiàng)目的指針數(shù)組,所以它支持基于索引的訪問(wèn),而且當(dāng)項(xiàng)目的數(shù)目小于組,所以它支持基于索引的訪問(wèn),而且當(dāng)項(xiàng)目的數(shù)目小于1000時(shí),可以實(shí)現(xiàn)在列表中間進(jìn)時(shí),可以實(shí)現(xiàn)在列表中間進(jìn)行快速的插入操作。行快速的插入操作。QList提供了很多方便的接口函數(shù)來(lái)操作列表中的項(xiàng)目,例如:提供了很多方便的接口

43、函數(shù)來(lái)操作列表中的項(xiàng)目,例如:n插入操作插入操作insert();n替換操作替換操作replace();n移除操作移除操作removeAt();n移動(dòng)操作移動(dòng)操作move();n交換操作交換操作swap();n在表尾添加項(xiàng)目在表尾添加項(xiàng)目append();n在表頭添加項(xiàng)目在表頭添加項(xiàng)目prepend();n移除第一個(gè)項(xiàng)目移除第一個(gè)項(xiàng)目removeFirst();n移除最后一個(gè)項(xiàng)目移除最后一個(gè)項(xiàng)目removeLast();n從列表中移除一項(xiàng)并獲取這個(gè)項(xiàng)目從列表中移除一項(xiàng)并獲取這個(gè)項(xiàng)目takeAt(),還有相應(yīng)的,還有相應(yīng)的takeFirst()和和takeLast();n獲取一個(gè)項(xiàng)目的索引獲取一

44、個(gè)項(xiàng)目的索引indexOf();n判斷是否含有相應(yīng)的項(xiàng)目判斷是否含有相應(yīng)的項(xiàng)目contains();n獲取一個(gè)項(xiàng)目出現(xiàn)的次數(shù)獲取一個(gè)項(xiàng)目出現(xiàn)的次數(shù)count()。 對(duì)于對(duì)于QList,可以使用,可以使用“”操作符來(lái)向列表中插入項(xiàng)目,也可以使用操作符來(lái)向列表中插入項(xiàng)目,也可以使用“ ”操作符通過(guò)索操作符通過(guò)索引來(lái)訪問(wèn)一個(gè)項(xiàng)目,其中項(xiàng)目是從引來(lái)訪問(wèn)一個(gè)項(xiàng)目,其中項(xiàng)目是從0開(kāi)始編號(hào)的。不過(guò),對(duì)于只讀的訪問(wèn),另一種方法是開(kāi)始編號(hào)的。不過(guò),對(duì)于只讀的訪問(wèn),另一種方法是使用使用at()函數(shù),它比函數(shù),它比“ ”操作符要快很多。操作符要快很多。 例如:例如: QList list; list aa bb c

45、c; / 插入項(xiàng)目插入項(xiàng)目 if(list1 = bb) list1 = ab; list.replace(2,bc); / 將將“cc”換為換為“bc” qDebug() the list is: ; / 輸出整個(gè)列表輸出整個(gè)列表 for(int i=0; ilist.size(); +i) qDebug() list.at(i); / 現(xiàn)在列表為現(xiàn)在列表為aa ab bc list.append(dd); / 在列表尾部添加在列表尾部添加 list.prepend(mm); / 在列表頭部添加在列表頭部添加 QString str = list.takeAt(2); / 從列表中刪除第從列

46、表中刪除第3個(gè)項(xiàng)目,并獲取它個(gè)項(xiàng)目,并獲取它 qDebug() at(2) item is: str; qDebug() the list is: ; for(int i=0; ilist.size(); +i) qDebug() list.at(i); / 現(xiàn)在列表為現(xiàn)在列表為mm aa bc dd QMap類是一個(gè)容器類,它提供了一個(gè)基于跳躍列表的字典(類是一個(gè)容器類,它提供了一個(gè)基于跳躍列表的字典(a skip-list-based dictionary)。)。QMap是是Qt的通用容器類之一,它存儲(chǔ)(鍵,值)對(duì)并提供了的通用容器類之一,它存儲(chǔ)(鍵,值)對(duì)并提供了與鍵相關(guān)的值的快速查找。

47、與鍵相關(guān)的值的快速查找。QMap中提供了很多方便的接口函數(shù),例如:中提供了很多方便的接口函數(shù),例如:n插入操作插入操作insert();n獲取值獲取值value();n是否包含一個(gè)鍵是否包含一個(gè)鍵contains();n刪除一個(gè)鍵刪除一個(gè)鍵remove();n刪除一個(gè)鍵并獲取該鍵對(duì)應(yīng)的值刪除一個(gè)鍵并獲取該鍵對(duì)應(yīng)的值take();n清空操作清空操作clear();n插入一鍵多值插入一鍵多值insertMulti()。 可以使用可以使用“ ”操作符插入一個(gè)鍵值對(duì)或者獲取一個(gè)鍵的值,不過(guò)當(dāng)使用該操作符獲取操作符插入一個(gè)鍵值對(duì)或者獲取一個(gè)鍵的值,不過(guò)當(dāng)使用該操作符獲取一個(gè)不存在的鍵的值時(shí),會(huì)默認(rèn)向一個(gè)

48、不存在的鍵的值時(shí),會(huì)默認(rèn)向map中插入該鍵,為了避免這個(gè)情況,可以使用中插入該鍵,為了避免這個(gè)情況,可以使用value()函數(shù)來(lái)獲取鍵的值。當(dāng)使用函數(shù)來(lái)獲取鍵的值。當(dāng)使用value()函數(shù)時(shí),如果指定的鍵不存在,那么默認(rèn)會(huì)函數(shù)時(shí),如果指定的鍵不存在,那么默認(rèn)會(huì)返回返回0,可以在使用該函數(shù)時(shí)提供參數(shù)來(lái)更改這個(gè)默認(rèn)返回的值。,可以在使用該函數(shù)時(shí)提供參數(shù)來(lái)更改這個(gè)默認(rèn)返回的值。QMap默認(rèn)是一個(gè)鍵默認(rèn)是一個(gè)鍵對(duì)應(yīng)一個(gè)值的,但是也可以使用對(duì)應(yīng)一個(gè)值的,但是也可以使用insertMulti()進(jìn)行一鍵多值的插入,對(duì)于一鍵多值的進(jìn)行一鍵多值的插入,對(duì)于一鍵多值的情況,更方便的是使用情況,更方便的是使用QM

49、ap的子類的子類QMultiMap。 例如:例如: QMap map; mapone = 1; / 向向map中插入中插入(one,1) mapthree = 3; map.insert(seven,7); / 使用使用insert()函數(shù)進(jìn)行插入函數(shù)進(jìn)行插入 / 獲取鍵的值,使用獲取鍵的值,使用“ ”操作符時(shí),如果操作符時(shí),如果map中沒(méi)有該鍵,那么會(huì)自動(dòng)插入中沒(méi)有該鍵,那么會(huì)自動(dòng)插入 int value1 = mapsix; qDebug() value1: value1; qDebug() contains six ? map.contains(six); / 使用使用value()函數(shù)

50、獲取鍵的值,這樣當(dāng)鍵不存在時(shí)不會(huì)自動(dòng)插入函數(shù)獲取鍵的值,這樣當(dāng)鍵不存在時(shí)不會(huì)自動(dòng)插入 int value2 = map.value(five); qDebug() value2: value2; qDebug() contains five ? map.contains(five); / 當(dāng)鍵不存在時(shí),當(dāng)鍵不存在時(shí),value()默認(rèn)返回默認(rèn)返回0,這里可以設(shè)定該值,比如這里設(shè)置為,這里可以設(shè)定該值,比如這里設(shè)置為9 int value3 = map.value(nine,9); qDebug() value3: value3;嵌套和賦值嵌套和賦值n容器也可以嵌套使用,例如容器也可以嵌套使用,

51、例如QMapQString,QList ,這里鍵的類,這里鍵的類型是型是QString,而值的類型是,而值的類型是QList,需要注意,在后面的,需要注意,在后面的“ ”符號(hào)之間要有一個(gè)空格,不然編譯器會(huì)將它當(dāng)做符號(hào)之間要有一個(gè)空格,不然編譯器會(huì)將它當(dāng)做“”操作符對(duì)待。操作符對(duì)待。n在各種容器中所存儲(chǔ)的值的類型可以是任何的可賦值的數(shù)據(jù)類型,該類在各種容器中所存儲(chǔ)的值的類型可以是任何的可賦值的數(shù)據(jù)類型,該類型需要有一個(gè)默認(rèn)的構(gòu)造函數(shù),一個(gè)拷貝構(gòu)造函數(shù)和一個(gè)賦值操作運(yùn)算型需要有一個(gè)默認(rèn)的構(gòu)造函數(shù),一個(gè)拷貝構(gòu)造函數(shù)和一個(gè)賦值操作運(yùn)算符,像基本的類型符,像基本的類型double,指針類型,指針類型,Q

52、t的數(shù)據(jù)類型如的數(shù)據(jù)類型如QString、QDate、QTime等。但是等。但是QObject以及以及QObject的子類都不能存儲(chǔ)在容的子類都不能存儲(chǔ)在容器中,不過(guò),可以存儲(chǔ)這些類的指針,例如器中,不過(guò),可以存儲(chǔ)這些類的指針,例如QList。 遍歷容器遍歷容器 遍歷一個(gè)容器可以使用迭代器(遍歷一個(gè)容器可以使用迭代器(iterators)來(lái)完成,迭代器提供了一)來(lái)完成,迭代器提供了一個(gè)統(tǒng)一的方法來(lái)訪問(wèn)容器中的項(xiàng)目。個(gè)統(tǒng)一的方法來(lái)訪問(wèn)容器中的項(xiàng)目。Qt的容器類提供了兩種類型的迭的容器類提供了兩種類型的迭代器:代器:nJava風(fēng)格迭代器風(fēng)格迭代器nSTL風(fēng)格迭代器風(fēng)格迭代器 如果只是想按順序遍歷一

53、個(gè)容器中的項(xiàng)目,那么還可以使用如果只是想按順序遍歷一個(gè)容器中的項(xiàng)目,那么還可以使用Qt的:的:nforeach關(guān)鍵字關(guān)鍵字Java風(fēng)格迭代器風(fēng)格迭代器 Java風(fēng)格迭代器在使用時(shí)比風(fēng)格迭代器在使用時(shí)比STL風(fēng)格迭代器要方便很多,風(fēng)格迭代器要方便很多,但是在性能上稍微弱于后者。對(duì)于每一個(gè)容器類,都有兩但是在性能上稍微弱于后者。對(duì)于每一個(gè)容器類,都有兩個(gè)個(gè)Java風(fēng)格迭代器數(shù)據(jù)類型:一個(gè)提供只讀訪問(wèn),一個(gè)風(fēng)格迭代器數(shù)據(jù)類型:一個(gè)提供只讀訪問(wèn),一個(gè)提供讀寫(xiě)訪問(wèn)。提供讀寫(xiě)訪問(wèn)。 QList示例:示例: QList list; list A B C D; QListIterator i(list); /

54、 創(chuàng)建列表的只讀迭代器,將創(chuàng)建列表的只讀迭代器,將list作為參數(shù)作為參數(shù) qDebug() the forward is :; while (i.hasNext() / 正向遍歷列表,結(jié)果為正向遍歷列表,結(jié)果為A,B,C,D qDebug() i.next(); qDebug() the backward is :; while (i.hasPrevious() / 反向遍歷列表,結(jié)果為反向遍歷列表,結(jié)果為D,C,B,A qDebug() i.previous(); 這里先創(chuàng)建了一個(gè)這里先創(chuàng)建了一個(gè)QList列表列表list,然后使用,然后使用list作為參數(shù)創(chuàng)建了一個(gè)列表的只讀迭作為參數(shù)創(chuàng)

55、建了一個(gè)列表的只讀迭代器。這時(shí),迭代器指向列表的第一個(gè)項(xiàng)目的前面(這里是指向項(xiàng)目代器。這時(shí),迭代器指向列表的第一個(gè)項(xiàng)目的前面(這里是指向項(xiàng)目“A”的前的前面)。然后使用面)。然后使用hasNext()函數(shù)來(lái)檢查在該迭代器后面是否還有項(xiàng)目,如果還有函數(shù)來(lái)檢查在該迭代器后面是否還有項(xiàng)目,如果還有項(xiàng)目,那么使用項(xiàng)目,那么使用next()來(lái)跳過(guò)這個(gè)項(xiàng)目,來(lái)跳過(guò)這個(gè)項(xiàng)目,next()函數(shù)會(huì)返回它所跳過(guò)的項(xiàng)目。當(dāng)正函數(shù)會(huì)返回它所跳過(guò)的項(xiàng)目。當(dāng)正向遍歷結(jié)束后,迭代器會(huì)指向列表最后一個(gè)項(xiàng)目的后面,這時(shí)可以使用向遍歷結(jié)束后,迭代器會(huì)指向列表最后一個(gè)項(xiàng)目的后面,這時(shí)可以使用hasPrevious()和和previ

56、ous()來(lái)進(jìn)行反向遍歷??梢钥吹?,來(lái)進(jìn)行反向遍歷??梢钥吹剑琂ava風(fēng)格迭代器是指風(fēng)格迭代器是指向項(xiàng)目之間的,而不是直接指向項(xiàng)目。所以,迭代器或者指向容器的最前面,或向項(xiàng)目之間的,而不是直接指向項(xiàng)目。所以,迭代器或者指向容器的最前面,或者指向兩個(gè)項(xiàng)目之間,或者指向容器的最后面。者指向兩個(gè)項(xiàng)目之間,或者指向容器的最后面。QMap示例:示例:QMap map; map.insert(Paris, France); map.insert(Guatemala City, Guatemala); map.insert(Mexico City, Mexico); map.insert(Moscow, R

57、ussia); QMapIterator i(map); while(i.hasNext() i.next(); qDebug() i.key() : i.value(); if(i.findPrevious(Mexico) qDebug() “find Mexico”; / 向前查找鍵的值向前查找鍵的值 這里在這里在QMap中存儲(chǔ)了一些(首都,國(guó)家)鍵值對(duì),然后刪除了包含以中存儲(chǔ)了一些(首都,國(guó)家)鍵值對(duì),然后刪除了包含以“City”字字符串結(jié)尾的鍵的項(xiàng)目。對(duì)于符串結(jié)尾的鍵的項(xiàng)目。對(duì)于QMap的遍歷,可以先使用的遍歷,可以先使用next()函數(shù),然后再使用函數(shù),然后再使用key()和和val

58、ue()來(lái)獲取鍵和值的信息。來(lái)獲取鍵和值的信息。 STL風(fēng)格迭代器風(fēng)格迭代器 STL風(fēng)格迭代器兼容風(fēng)格迭代器兼容Qt和和STL的通用算法(的通用算法(generic algorithms),而且在),而且在速度上進(jìn)行了優(yōu)化。對(duì)于每一個(gè)容器類,都有兩個(gè)速度上進(jìn)行了優(yōu)化。對(duì)于每一個(gè)容器類,都有兩個(gè)STL風(fēng)格迭代器類型:一風(fēng)格迭代器類型:一個(gè)提供了只讀訪問(wèn),另一個(gè)提供了讀寫(xiě)訪問(wèn)。因?yàn)橹蛔x迭代器比讀寫(xiě)迭代器個(gè)提供了只讀訪問(wèn),另一個(gè)提供了讀寫(xiě)訪問(wèn)。因?yàn)橹蛔x迭代器比讀寫(xiě)迭代器要快很多,所以應(yīng)盡可能使用只讀迭代器。要快很多,所以應(yīng)盡可能使用只讀迭代器。QList示例:示例: QList list; list

59、 A B C D; QList:iterator i; / 使用讀寫(xiě)迭代器使用讀寫(xiě)迭代器 qDebug() the forward is :; for (i = list.begin(); i != list.end(); +i) *i = (*i).toLower(); / 使用使用QString的的toLower()函數(shù)轉(zhuǎn)換為小寫(xiě)函數(shù)轉(zhuǎn)換為小寫(xiě) qDebug() *i; / 結(jié)果為結(jié)果為a,b,c,d qDebug() the backward is :; while (i != list.begin() -i; qDebug() *i; / 結(jié)果為結(jié)果為d,c,b,a QList:con

60、st_iterator j; / 使用只讀迭代器使用只讀迭代器 qDebug() the forward is :; for (j = list.constBegin(); j != list.constEnd(); +j) qDebug() *j; / 結(jié)果為結(jié)果為a,b,c,d STL風(fēng)格迭代器的風(fēng)格迭代器的API模仿了數(shù)組的指針,例如,使用模仿了數(shù)組的指針,例如,使用“+”操作符來(lái)向后移動(dòng)迭代器操作符來(lái)向后移動(dòng)迭代器使其指向下一個(gè)項(xiàng)目;使用使其指向下一個(gè)項(xiàng)目;使用“*”操作符返回迭代器指向的項(xiàng)目等。需要說(shuō)明的是,不操作符返回迭代器指向的項(xiàng)目等。需要說(shuō)明的是,不同于同于Java風(fēng)格迭代器,

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論