Qt入門教程第7章(3課時)_第1頁
Qt入門教程第7章(3課時)_第2頁
Qt入門教程第7章(3課時)_第3頁
Qt入門教程第7章(3課時)_第4頁
Qt入門教程第7章(3課時)_第5頁
已閱讀5頁,還剩61頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

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

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

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

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

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

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

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

8、lic、private和和protected等限定符,因為等限定符,因為只有定義該信號的類及其子類才可以發(fā)射該信號。只有定義該信號的類及其子類才可以發(fā)射該信號。n信號只用聲明,不需要也不能對它進(jìn)行定義實現(xiàn)。信號只用聲明,不需要也不能對它進(jìn)行定義實現(xiàn)。n信號沒有返回值,只能是信號沒有返回值,只能是void類型的。類型的。n只有只有QObject類及其子類派生的類才能使用信號和槽機制,使用信號類及其子類派生的類才能使用信號和槽機制,使用信號和槽,還必須在類聲明的最開始處添加和槽,還必須在類聲明的最開始處添加Q_OBJECT宏。宏。發(fā)射信號發(fā)射信號例如:例如:void MyDialog:on_pus

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

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

11、和信的,也可以像調(diào)用一個普通函數(shù)一樣來調(diào)用槽。槽的最大特點就是可以和信號關(guān)聯(lián)。號關(guān)聯(lián)。信號和槽的關(guān)聯(lián)信號和槽的關(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它的第一個參數(shù)為發(fā)送信號的對象,例如這里的它的第一個參數(shù)為發(fā)送信號的對象,例如這里的dlg;n第二個參數(shù)是要發(fā)送的信號,這里是第二個參數(shù)是要發(fā)送的信號,這里是SIGNAL(dlgReturn(int);n第三個參數(shù)是接收信號的對象,這里是第三個參數(shù)是接收信號的對象,這里是this,表明是本部件,即,表明是本部件,即Widget,當(dāng)這個參數(shù)為,當(dāng)這個參數(shù)為this時,也時,也可以將這個參數(shù)省略掉,因為可以將這個參數(shù)省略掉,因為connect()函數(shù)還有另外一個重載形式,該參數(shù)默認(rèn)為函數(shù)還有另外一個重載形式,該參數(shù)默

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

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

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

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

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

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

19、然,這點性能差異通常在一個應(yīng)用程序中是很難體現(xiàn)回調(diào)機制的。當(dāng)然,這點性能差異通常在一個應(yīng)用程序中是很難體現(xiàn)出來的。出來的。屬性系統(tǒng)屬性系統(tǒng) Qt提供了強大的基于元對象系統(tǒng)的屬性系統(tǒng),可以在能夠運行提供了強大的基于元對象系統(tǒng)的屬性系統(tǒng),可以在能夠運行Qt的平臺上支持任意的標(biāo)準(zhǔn)的平臺上支持任意的標(biāo)準(zhǔn)C+編譯器。要聲明一個屬性,那么該類必須繼承自編譯器。要聲明一個屬性,那么該類必須繼承自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()宏在元對象系統(tǒng)中進(jìn)行注冊,這樣以后才可以使用宏在元對象系統(tǒng)中進(jìn)行注冊,這樣以后才可以使用QObject:setProperty()函數(shù)來使用該屬性。函數(shù)來使用該屬性

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

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

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

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

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

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

27、屬性值改變時發(fā)射該信號 signals: void userNameChanged(QString); / 聲明聲明NOTIFY通知消息通知消息private: QString m_userName; / 私有變量,存放私有變量,存放userName屬性的值屬性的值;使用自定義的屬性:使用自定義的屬性: MyClass *my = new MyClass(this); / 創(chuàng)建創(chuàng)建MyClass類實例類實例 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(); 對象樹和擁有權(quán)對象樹和擁有權(quán) Qt中使用對象樹(中使用

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

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

31、鈕和息對話框中的按鈕和標(biāo)簽也會被銷毀,這也正是我們所希望的,因為按鈕和標(biāo)簽是消息對話框的子部件。當(dāng)然,也可以自己來銷毀一個子對象。標(biāo)簽是消息對話框的子部件。當(dāng)然,也可以自己來銷毀一個子對象。 示例示例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窗口被銷毀時,將輸出信息。窗口被銷毀時,將輸出信息。 運行程序,然后關(guān)閉窗口,在運行程序,然后關(guān)閉窗口,在Qt Creator的應(yīng)用程序輸出欄中的輸出信息為:的應(yīng)用程序輸出欄中的輸出信息為:delete widget delete button可以看到,當(dāng)關(guān)閉窗口后,因為該窗口是頂層窗口,所以應(yīng)用程序要銷毀該窗口部件可以看到,當(dāng)關(guān)閉窗口后,因為該窗口是頂層窗口,所以應(yīng)用程序要銷毀該窗口部件(如果不是頂層窗口,那么關(guān)閉時只是隱藏,不會被銷毀),而當(dāng)窗口部件銷毀時會(如果不是頂層窗口,那么關(guān)閉時只是隱藏,不會被銷毀),而當(dāng)窗口部件銷毀時會自動銷毀其子部件。這也就是

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

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

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

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

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

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

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

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

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

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

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

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

45、c; / 插入項目插入項目 if(list1 = bb) list1 = ab; list.replace(2,bc); / 將將“cc”換為換為“bc” qDebug() the list is: ; / 輸出整個列表輸出整個列表 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個項目,并獲取它個項目,并獲取它 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類是一個容器類,它提供了一個基于跳躍列表的字典(類是一個容器類,它提供了一個基于跳躍列表的字典(a skip-list-based dictionary)。)。QMap是是Qt的通用容器類之一,它存儲(鍵,值)對并提供了的通用容器類之一,它存儲(鍵,值)對并提供了與鍵相關(guān)的值的快速查找。

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

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

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

50、獲取鍵的值,這樣當(dāng)鍵不存在時不會自動插入函數(shù)獲取鍵的值,這樣當(dāng)鍵不存在時不會自動插入 int value2 = map.value(five); qDebug() value2: value2; qDebug() contains five ? map.contains(five); / 當(dāng)鍵不存在時,當(dāng)鍵不存在時,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,需要注意,在后面的,需要注意,在后面的“ ”符號之間要有一個空格,不然編譯器會將它當(dāng)做符號之間要有一個空格,不然編譯器會將它當(dāng)做“”操作符對待。操作符對待。n在各種容器中所存儲的值的類型可以是任何的可賦值的數(shù)據(jù)類型,該類在各種容器中所存儲的值的類型可以是任何的可賦值的數(shù)據(jù)類型,該類型需要有一個默認(rèn)的構(gòu)造函數(shù),一個拷貝構(gòu)造函數(shù)和一個賦值操作運算型需要有一個默認(rèn)的構(gòu)造函數(shù),一個拷貝構(gòu)造函數(shù)和一個賦值操作運算符,像基本的類型符,像基本的類型double,指針類型,指針類型,Q

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

53、個容器中的項目,那么還可以使用如果只是想按順序遍歷一個容器中的項目,那么還可以使用Qt的:的:nforeach關(guān)鍵字關(guān)鍵字Java風(fēng)格迭代器風(fēng)格迭代器 Java風(fēng)格迭代器在使用時比風(fēng)格迭代器在使用時比STL風(fēng)格迭代器要方便很多,風(fēng)格迭代器要方便很多,但是在性能上稍微弱于后者。對于每一個容器類,都有兩但是在性能上稍微弱于后者。對于每一個容器類,都有兩個個Java風(fēng)格迭代器數(shù)據(jù)類型:一個提供只讀訪問,一個風(fēng)格迭代器數(shù)據(jù)類型:一個提供只讀訪問,一個提供讀寫訪問。提供讀寫訪問。 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)建了一個這里先創(chuàng)建了一個QList列表列表list,然后使用,然后使用list作為參數(shù)創(chuàng)建了一個列表的只讀迭作為參數(shù)創(chuàng)

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

56、ous()來進(jìn)行反向遍歷。可以看到,來進(jìn)行反向遍歷??梢钥吹?,Java風(fēng)格迭代器是指風(fē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中存儲了一些(首都,國家)鍵值對,然后刪除了包含以中存儲了一些(首都,國家)鍵值對,然后刪除了包含以“City”字字符串結(jié)尾的鍵的項目。對于符串結(jié)尾的鍵的項目。對于QMap的遍歷,可以先使用的遍歷,可以先使用next()函數(shù),然后再使用函數(shù),然后再使用key()和和val

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

59、 A B C D; QList:iterator i; / 使用讀寫迭代器使用讀寫迭代器 qDebug() the forward is :; for (i = list.begin(); i != list.end(); +i) *i = (*i).toLower(); / 使用使用QString的的toLower()函數(shù)轉(zhuǎn)換為小寫函數(shù)轉(zhuǎn)換為小寫 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ù)組的指針,例如,使用“+”操作符來向后移動迭代器操作符來向后移動迭代器使其指向下一個項目;使用使其指向下一個項目;使用“*”操作符返回迭代器指向的項目等。需要說明的是,不操作符返回迭代器指向的項目等。需要說明的是,不同于同于Java風(fēng)格迭代器,

溫馨提示

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

評論

0/150

提交評論