QT4中文教程 經(jīng)典教程_第1頁
QT4中文教程 經(jīng)典教程_第2頁
QT4中文教程 經(jīng)典教程_第3頁
QT4中文教程 經(jīng)典教程_第4頁
QT4中文教程 經(jīng)典教程_第5頁
已閱讀5頁,還剩154頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、c+ gui programming with qt 4c+ gui programming with qt 4 by jasmin blanchette, mark summerfield . publisher: prentice hall pub date: june 21, 2006 print isbn-10: 0-13-187249-4 print isbn-13: 978-0-13-187249-3 pages: 560學(xué)習(xí),使用qt已經(jīng)將近兩年了,最開始的時候用qt3,后來升級到qt4.1,自認(rèn)為對qt的gui編程部分還是很 熟悉的。遺憾的是qt的參考書少之又少,一般就是看文檔

2、和c+ gui programming with qt 3,這本書是免費(fèi)提供的,讓我對qt,trolltech公司有了更多的了解。我這個人就是這樣,學(xué)習(xí)什么都喜歡了解這個東東發(fā)展的歷史,雖然對學(xué)習(xí)并沒 有太多幫助。升級到qt4以后,api有了很多變化,苦盼一本系統(tǒng)的參考書,很久,c+ gui programming with qt 4才得以面世,終于盼到后卻遺憾的發(fā)現(xiàn)這本沒有提供免費(fèi)的電子版,今天,一個偶然的機(jī)會,得到y(tǒng)imin網(wǎng)友的幫助,得到一份電子版,真是很謝謝他,他的 blog/blog。c+ gui programming with qt 4就是這樣一

3、本參考書,從易到難,從最經(jīng)典的hello qt開始,到構(gòu)建復(fù)雜的程序。我從現(xiàn)在開始閱讀學(xué)習(xí),同時也把部分心得寫出來,發(fā)到這里,也希望對qt的學(xué)習(xí)者們有所幫助。這對我來說有點(diǎn)難度,懶人那, 不過一定盡最大努力堅持寫完我熟悉的部分。加油!qt 的創(chuàng)建者h(yuǎn)aarard nord(trolltech公司的ceo)和eirik chambe-eng(trolltech公司的總裁)是一家瑞典公司的同事。那時(1990)他們在做一個項目,這個項目需要在 unix,macintosh,windows上運(yùn)行同一個gui,象我們現(xiàn)在的開發(fā)人員一樣,工作的很累,當(dāng)時可是沒有如今這么多的開發(fā)工具。一天他們 工作之余去

4、公園散步,曬太陽,喝咖啡。haarard說:“we need an object-oriented display system?!边@成為了后來qt最重要的思想:提供面向?qū)ο蟮目缙脚_的gui框架??吹竭@里小女我不僅感慨:什么時候我們的程序員們可以在工作的時候出 來走走,只有在輕松愉快的環(huán)境中才會生產(chǎn)出出色的成果。在沉悶的辦公室里,只是機(jī)械的堆砌代碼而已。所做就做,haarard開始寫代碼,eirik負(fù)責(zé)設(shè)計,qt在襁褓中逐漸成長,在開始蹣跚學(xué)步的時候(1993年),他們開始讓qt闖蕩江湖,兩個人開始了創(chuàng)業(yè)的艱辛歷程。對這兩個年輕人,1994年是非常艱難的一年,他們沒有客戶,沒有錢,只有還沒有完

5、全實現(xiàn)的產(chǎn)品。關(guān)鍵時刻,他們的妻子幫他們渡過了難關(guān)。字母q作為所有類的前綴,是因為haarard手寫這個字母看起來特別的漂亮,字母t代表“toolkit”,在xt,x toolkit等中得到靈感。1995年開始出現(xiàn)轉(zhuǎn)機(jī),他們得到了一個合同。這一年,他們雇傭了arnt gulbrandsen,他在trolltech工作了六年,他為qt實現(xiàn)了優(yōu)秀的文檔系統(tǒng)。1995年5月,qt 0.9發(fā)布,有商業(yè)和開源兩個版本。96年9月,qt1.0發(fā)布。1997年,matthias ettrich開始用qt開發(fā)kde,使qt成為linux上gui開發(fā)的 事實上的標(biāo)準(zhǔn)。1999年,qt 2 發(fā)布。2000年,qt

6、opia發(fā)布。支持linux嵌入式開發(fā)。2001年,qt 3 發(fā)布。2005年, qt 4 發(fā)布。十年來,qt就是這樣從不知名的一個產(chǎn)品,發(fā)展到現(xiàn)在擁有全世界范圍內(nèi)成千上萬的客戶。差不多所有的程序教材都從hello 開始,下面就是這個程序的qt版本。1 #include 2 #include 3 int main(int argc, char *argv)4 5 qapplication app(argc, argv);6 qlabel *label = new qlabel(hello qt!);7 label-show();8 return app.exec();9 按行解析以上9行代碼第

7、一,二行:是代碼中需要使用的類的頭文件。在qt4中,可以寫成的格式,當(dāng)然也可寫成“qapplication.h”。第三行:是main函數(shù)的標(biāo)準(zhǔn)寫法第五行:創(chuàng)建一個qapplication對象,管理應(yīng)用程序的資源。第六行:qlabel對象,qlabel是一個qt提供的小控件,顯示一行文本。第七行:顯示qlabel。第八行:qapplication.exec(),讓程序進(jìn)入消息循環(huán)。等待可能的菜單,工具條,鼠標(biāo)等的輸入,進(jìn)行響應(yīng)。將以上代碼放到名為hello.cpp中,保存,編譯過程如下:qmake -project,qmake命令創(chuàng)建,是平臺無關(guān)的工程文件。在

8、所在目錄下,運(yùn)行make(unix)或者nmake(windows)。第6行代碼還可以如下替換:qlabel *label = new qlabel(hello qt!); 這里面包含了html文本,顯示的字體,顏色會改變。實際程序中,下面兩行是比不可少的。qapplication app(argc, argv);return app.exec();連接信號和響應(yīng)函數(shù)這個例子用來說明怎么響應(yīng)信號,和hello程序的源代碼相似,原來的label用一個按鈕代替,點(diǎn)擊時退出程序。源程序如下:1 #include 2 #include 3 int main(int argc, char *argv)4

9、 5 qapplication app(argc, argv);6 qpushbutton *button = new qpushbutton(quit);7 qobject:connect(button, signal(clicked(),8 &app, slot(quit();9 button-show();10 return app.exec();11 當(dāng)有所動作或者狀態(tài)改變,qt的控件會發(fā)出消息(signal),例如,當(dāng)點(diǎn)擊按鈕時,按鈕會發(fā)送clicked()消息,這個消息可以連接到一個 函數(shù)上(這個函數(shù)在這里成為slot)。這樣,當(dāng)一個消息發(fā)送時,slot函數(shù)可以自動執(zhí)行。在這個例子

10、中,我們連接了按鈕的clicked信號和 qapplication的quit函數(shù),語法如第七,八行所示。編譯以上程序,將以上代碼放在quit.cpp文件中,保存。依次運(yùn)行qmake -projectqmake make(unix or linux) or nmake(windows)然后運(yùn)行程序,點(diǎn)擊quit按鈕,程序?qū)兄?。這個應(yīng)用程序用了三個窗口部件:一個qspinbox(微調(diào)框)、一個qslider(滑塊)和一個qwidget。其中qwidget是這個應(yīng)用程序的主窗口,也是qspinbox和qslider的父對象,qwidget自己沒有父對象。qwidget的構(gòu)造函數(shù)以

11、及它的所有子類都會帶一個參數(shù)qwidget*,以用來說明誰是它們的父窗口部件在這個小節(jié)中,我們說明在一個窗口中如何排列多個控件。學(xué)習(xí)利用signal和slot的方法使控件同步。程序要求用戶通過spin box或者slider輸入年齡。程 序中使用了三個控件:qspinbox,qslider和qwidget。qwidget是這個程序的主窗口。qspinbox和qslider被放在 qwidget中;他們是qwidget的children。反過來,我們也可以稱qwidget是qspinbox和qslider的parent。 qwidget沒有parent,因為它是程序的頂層窗口。在qwidget及

12、其子類的構(gòu)造函數(shù)中,都有一個qwidget*參數(shù),用來指定它們的父控 件。源代碼如下:1 #include 2 #include 3 #include 4 #include 5 int main(int argc, char *argv)6 7 qapplication app(argc, argv);8 qwidget *window = new qwidget;9 window-setwindowtitle(enter your age);10 qspinbox *spinbox = new qspinbox;11 qslider *slider = new qslider(qt:hori

13、zontal);12 spinbox-setrange(0, 130);13 slider-setrange(0, 130);14 qobject:connect(spinbox, signal(valuechanged(int),15 slider, slot(setvalue(int);16 qobject:connect(slider, signal(valuechanged(int),17 spinbox, slot(setvalue(int);18 spinbox-setvalue(35);19 qhboxlayout *layout = new qhboxlayout;20 lay

14、out-addwidget(spinbox);21 layout-addwidget(slider);22 window-setlayout(layout);23 window-show();24 return app.exec();25 第 8,9行建立程序的主窗口控件,設(shè)置標(biāo)題。第10到13行創(chuàng)建主窗口的children,并設(shè)置允許值的范圍。第14到第17行是spinbox和 slider的連接,以使之同步顯示同一個年齡值。不管那個控件的值發(fā)生變化,都會發(fā)出valuechanged(int)信號,另一個控件的 setvalue(int)函數(shù)就會為這個控件設(shè)置一個新值。第18行將spinbo

15、x的值設(shè)置為35,這時spinbox發(fā)出 valuechanged(int)信號,int的參數(shù)值為35,這個參數(shù)傳遞給slider的setvalue(int)函數(shù),將slider的值也設(shè) 置為35。同理,slider也會發(fā)出valuechanged(int)信號,觸發(fā)spinbox的setvalue(int)函數(shù)。這個時候,因為 spinbox的當(dāng)前值就是35,所以spinbox不會發(fā)送任何信號,不會引起死循環(huán)。在第19至22行,我們使用了一個布局管理器排列spinbox和slider控件。布局管理器能夠根據(jù)需要確定控件的大小和位置。qt有三個主要的布局管理器:qhboxlayout:水平排列

16、控件。qvboxlayout:垂直排列控件。qgridlayout:按矩陣方式排列控件第 22行,qwidget:setlayout()把這個布局管理器放在window上。這個語句將spinbox和slider的“父”設(shè)為 window,即布局管理器所在的控件。如果一個控件由布局管理器確定它的大小和位置,那個創(chuàng)建它的時候就不必指定一個明確的“父”控件?,F(xiàn)在,雖然我們還沒有看見spinbox和slider控件的大小和位置,它們已經(jīng)水平排列好了。qhboxlayout能合理安排它們。我們不用在程序中考慮控件在屏幕上的大小和位置這些頭疼的事情了,交給布局管理器就萬事大吉。在qt中建立用戶界面就是這樣

17、簡單靈活。程序員的任務(wù)就是實例化所需要的控件,按照需要設(shè)置它們的屬性,把它們放到布局管理器中。界面中要完成任務(wù)由qt的signal和slot完成。 第一章就這樣翻譯完了,很快,因為簡單。好多地方?jīng)]有按照原書翻譯。從第二章開始,我會按照原書的結(jié)構(gòu)和標(biāo)題進(jìn)行翻譯,但是因為語言和敘述的關(guān)系,不會逐字翻譯,而是保持原書的內(nèi)容不變。翻譯這本書的主要目的是督促自己的學(xué)習(xí)。如果能夠給其他人提供幫助,更是欣喜。在這章介紹如何創(chuàng)建qt的對話框。對話框是程序和用戶交互的橋梁,提供了程序和用戶之間對話的一種方式。很多程序都是由一個主窗口,在這個主窗口中包含一個菜單條,多個工具條,和足夠多的對話框。也有些程序本身就是

18、一個對話框,直接相應(yīng)用戶的輸入請求。本章中我們首先會用代碼的方式創(chuàng)建我們的第一個對話框,然后用qt designer工具創(chuàng)建對話框。qt designer是一個可視化的工具,用它可以更快的創(chuàng)建,修改對話框。2.1派生對話框類(subclassing qdialog)第一個例子是一個用c+實現(xiàn)的查找對話框。我們把這個對話框?qū)崿F(xiàn)為一個類,這樣它就是一個獨(dú)立的控件,并有自己的信號(signal)和slot函數(shù)類的源代碼分別放在finddialog.h和finddialog.cpp中。首先看finddialog.h的代碼1 #ifndef finddialog_h2 #define finddialo

19、g_h3 #include 4 class qcheckbox;5 class qlabel;6 class qlineedit;7 class qpushbutton;8 class finddialog : public qdialog9 10 q_object11 public:12 finddialog(qwidget *parent = 0);13 signals:14 void findnext(const qstring &str, qt:casesensitivity cs);15 void findprevious(const qstring &str, qt:casesen

20、sitivity cs);16 private slots:17 void findclicked();18 void enablefindbutton(const qstring &text);19 private:20 qlabel *label;21 qlineedit *lineedit;22 qcheckbox *casecheckbox;23 qcheckbox *backwardcheckbox;24 qpushbutton *findbutton;25 qpushbutton *closebutton;26 ;27 #endif一共27行,第1,2,27行是為了避免頭文件被多次

21、包含。第3行包含qdialog頭文件,這個類從qdialog繼承,qdialog從qwidget繼承。第4至7行是用到的qt中類的前向聲明。通過前向聲明,編譯器就知道這個類已經(jīng)存在,而不用寫出包含的頭文件。這個問題稍后還要講。第8至26行是類finddialog的定義。第10行,q_object是一個宏定義,如果類里面用到了signal或者slots,就要聲明這個宏。第12行, finddialog(qwidget *parent = 0);構(gòu)造函數(shù)是qt控件類的標(biāo)準(zhǔn)格式,默認(rèn)的父參數(shù)為null,說明沒有父控件。第 13行,signal聲明了這個對話框發(fā)出的兩個信號,如果選擇向前查找,那么對話

22、框就發(fā)出findprevious()信號,否則,發(fā)出 findnext()信號。signal也是一個宏,在編譯之前,c+預(yù)處理把它變成標(biāo)準(zhǔn)的c+代碼。qt:casesensitivity是一個 枚舉類型,有qt:casesensitive和qt:caseinsensitive兩個值。在類的私有部分,聲明有兩個slot函數(shù)。為了實現(xiàn)這兩個函數(shù),需要用到對話框的其他控件的信息,所以保存了一些控件的指針。slot關(guān)鍵字和signal一樣,也是一個宏。對于私有成員變量,我們只是使用了它們的指針,沒有對它們進(jìn)行存取操作,編譯器不需要知道它們的詳細(xì)定義,所以只使用了這些類的前向聲明。當(dāng)然,也可以使用,等,

23、但是,使用前向聲明會讓編譯速度更快一些。下面看一下finddialog.cpp源文件代碼:文件頭和構(gòu)造函數(shù)部分1 #include 2 #include finddialog.h3 finddialog:finddialog(qwidget *parent)4 : qdialog(parent)5 6 label = new qlabel(tr(find &what:);7 lineedit = new qlineedit;8 label-setbuddy(lineedit);9 casecheckbox = new qcheckbox(tr(match &case);10 backwardc

24、heckbox = new qcheckbox(tr(search &backward);11 findbutton = new qpushbutton(tr(&find);12 findbutton-setdefault(true);13 findbutton-setenabled(false);14 closebutton = new qpushbutton(tr(close);15 connect(lineedit, signal(textchanged(const qstring &),16 this, slot(enablefindbutton(const qstring &);17

25、 connect(findbutton, signal(clicked(),18 this, slot(findclicked();19 connect(closebutton, signal(clicked(),20 this, slot(close();21 qhboxlayout *topleftlayout = new qhboxlayout;22 topleftlayout-addwidget(label);23 topleftlayout-addwidget(lineedit);24 qvboxlayout *leftlayout = new qvboxlayout;25 left

26、layout-addlayout(topleftlayout);26 leftlayout-addwidget(casecheckbox);27 leftlayout-addwidget(backwardcheckbox);28 qvboxlayout *rightlayout = new qvboxlayout;29 rightlayout-addwidget(findbutton);30 rightlayout-addwidget(closebutton);31 rightlayout-addstretch();32 qhboxlayout *mainlayout = new qhboxl

27、ayout;33 mainlayout-addlayout(leftlayout);34 mainlayout-addlayout(rightlayout);35 setlayout(mainlayout);36 setwindowtitle(tr(find);37 setfixedheight(sizehint().height();38 到這里finddialog的構(gòu)造函數(shù)就完成了。在傳見控件和布局時我們使用了new,一般情況下,我們還需要寫析構(gòu)函數(shù)delete這些控件。但是在qt中這是不需要的,當(dāng)父控件銷毀時,qt自動刪除它所有的子控件和布局。 下面是finddialog類的兩個slot

28、函數(shù):39 void finddialog:findclicked()40 41 qstring text = lineedit-text();42 qt:casesensitivity cs =43 casecheckbox-ischecked() ? qt:casesensitive44 : qt:caseinsensitive;45 if (backwardcheckbox-ischecked() 46 emit findprevious(text, cs);47 else 48 emit findnext(text, cs);49 50 51 void finddialog:enabl

29、efindbutton(const qstring &text)52 53 findbutton-setenabled(!text.isempty();54 當(dāng)用戶點(diǎn)擊findbutton按鈕,findclicked()就會調(diào)用,根據(jù)backwardcheckbox狀態(tài),他發(fā)出findprevious()或者findnext()信號。emit也是一個qt的宏。當(dāng)用戶改變lineedit中的文本,enablefindbutton()slot函數(shù)就會調(diào)用。如果輸入了文本,那么讓findbutton有效,否則就無效。最后,創(chuàng)建main.cpp測試finddialog對話框。1 #include 2

30、#include finddialog.h3 int main(int argc, char *argv)4 5 qapplication app(argc, argv);6 finddialog *dialog = new finddialog;7 dialog-show();8 return app.exec();9 運(yùn)行qmake編譯程序。由于在finddialog中包含了q_object宏,由qmake生成的makefile會保換特殊的規(guī)則運(yùn)行moc(qt的原對象編譯器)。為了確保moc正確工作,類定義必須放在頭文件而不能放在實現(xiàn)文件中。由moc生成的代碼中包含這個頭文件,并加入它自己

31、實現(xiàn)的c+代碼。使用了q_object宏的類必須運(yùn)行moc。如果使用qmake,那么makefile里自動包含相關(guān)的規(guī)則。如果忘記了運(yùn)行moc,就會發(fā)生連接錯誤。不同的編譯器給出的提示信息不同,有的會非常晦澀。gcc給出的錯誤信息如下: finddialog.o: in function finddialog:tr(char const*, char const*): /usr/lib/qt/src/corelib/global/qglobal.h:1430: undefined reference to finddialog:staticmetaobject visual c+中的輸出是這樣

32、: finddialog.obj : error lnk2001: unresolved external symbol public:virtual int _thiscall myclass:qt_metacall(enum qmetaobject :call,int,void * *)這時需要重新運(yùn)行qmake,更新makefile,然后編譯程序。運(yùn)行程序,如果看到了快鍵,測試alt+w,alt+c,alt+b,alt+f引發(fā)相應(yīng)的處理程序。使用tab鍵在將焦點(diǎn)改變到不同的控件上。默認(rèn)的tab鍵是控件創(chuàng)建的順序。qwidget:settaborder()可以改變這個順序。提供合適的tab

33、順序和快鍵可以讓用戶不用鼠標(biāo)也可以運(yùn)行程序,通過鍵盤可以快速控制程序。2.2深入信號和槽(signals and slots in depth)信號和槽是qt編程的一個重要部分。這個機(jī)制可以在對象之間彼此并不了解的情況下將它們的行為聯(lián)系起來。在前幾個例程中,我們已經(jīng)連接了信號和槽,聲明了控件自己的信號和槽,并實現(xiàn)了槽函數(shù),發(fā)送了信號?,F(xiàn)在來更深入了解這個機(jī)制。槽和普通的c+成員函數(shù)很像。它們可以是虛函數(shù)(virtual),也可被重載(overload),可以是公有的(public),保護(hù)的 (protective),也可是私有的(private),它們可以象任何c+成員函數(shù)一樣被調(diào)用,可以傳遞

34、任何類型的參數(shù)。不同在于一個槽函數(shù)能和 一個信號相連接,只要信號發(fā)出了,這個槽函數(shù)就會自動被調(diào)用。connect函數(shù)語法如下:connect(sender, signal(signal), receiver, slot(slot);sender和receiver是qobject對象指針,signal和slot是不帶參數(shù)的函數(shù)原型。signale()和slot()宏的作用是把他們轉(zhuǎn)換成字符串。在目前有的例子中,我們已經(jīng)連接了不同的信號和槽。實際使用中還要考慮如下一些規(guī)則:1、一個信號可以連接到多個槽:connect(slider, signal(valuechanged(int),spinbox

35、, slot(setvalue(int);connect(slider, signal(valuechanged(int),this, slot(updatestatusbarindicator(int);當(dāng)信號發(fā)出后,槽函數(shù)都會被調(diào)用,但是調(diào)用的順序是隨機(jī)的,不確定的。2、多個信號可以連接到一個槽connect(lcd, signal(overflow(), this, slot(handlematherror();connect(calculator, signal(divisionbyzero(),this, slot(handlematherror();任何一個信號發(fā)出,槽函數(shù)都會執(zhí)行

36、。3、一個信號可以和另一個信號相連connect(lineedit, signal(textchanged(const qstring &), this, signal(updaterecord(const qstring &);第一個信號發(fā)出后,第二個信號也同時發(fā)送。除此之外,信號與信號連接上和信號和槽連接相同。4、連接可以被刪除disconnect(lcd, signal(overflow(),this, slot(handlematherror();這個函數(shù)很少使用,一個對象刪除后,qt自動刪除這個對象的所有連接。信號和槽函數(shù)必須有著相同的參數(shù)類型,這樣信號和槽函數(shù)才能成功連接:conn

37、ect(ftp, signal(rawcommandreply(int, const qstring &),this, slot(processreply(int, const qstring &);如果信號里的參數(shù)個數(shù)多于槽函數(shù)的參數(shù),多余的參數(shù)被忽略:connect(ftp, signal(rawcommandreply(int, const qstring &),this, slot(checkerrorcode(int);如果參速類型不匹配,或者信號和槽不存在,在debug狀態(tài)時,qt會在運(yùn)行期間給出警告。如果信號和槽連接時包含了參數(shù)的名字,qt將會給出警告。以前我們列舉的例子中都是控

38、件的信號和槽。但是信號和槽機(jī)制在qobject中就實現(xiàn)了,可以實現(xiàn)在任何從qobject繼承的子類中。class employee : public qobject q_objectpublic: employee() mysalary = 0; int salary() const return mysalary; public slots: void setsalary(int newsalary);signals: void salarychanged(int newsalary);private: int mysalary;void employee:setsalary(int new

39、salary) if (newsalary != mysalary) mysalary = newsalary; emit salarychanged(mysalary); 注意,只有newsalary != mysalary時才發(fā)出salary-changed()信號,這樣避免了死循環(huán)的出現(xiàn)。qt的meta-object系統(tǒng)qt的一個最主要的成功是對c+擴(kuò)展,即把彼此獨(dú)立的軟件模塊連接起來,而不需要模塊間的任何細(xì)節(jié)。這 個機(jī)制就是meta-object系統(tǒng),它提供了兩個關(guān)鍵的用途:信號和槽和introspection(內(nèi)?。ntrospection功能允許應(yīng) 用程序在運(yùn)行時得到qobje

40、c它子類的“meta-information”,這對實現(xiàn)信號和槽是很必要的,包括全部信號和槽的列表,和類的名字。這個 機(jī)制還提供了屬性(在qt designer中使用)和文本翻譯(國際化)支持。它們構(gòu)成了qsa(qt script for application)的基礎(chǔ)。標(biāo)準(zhǔn)c+不提供qt meta-object系統(tǒng)需要的動態(tài)meta-information。qt提供了一個獨(dú)立的工具moc,通過定義q_object宏實現(xiàn)到c+函數(shù)的轉(zhuǎn)變。moc是用純c+實現(xiàn)的,因此可以使用在任何c+編譯器中。這個機(jī)制工作過程如下:q_object聲明了一些qobject子類必須實現(xiàn)的內(nèi)省函數(shù):metaobje

41、ct(),tr(),qt_metacall()等。qt的moc工具實現(xiàn)q_object宏聲明的函數(shù)和所有的信號。qobject成員函數(shù)connect()和disconnect()使用這些內(nèi)省函數(shù)實現(xiàn)信號和槽的連接。以上這些是通過qmake,moc和qobject自動處理的,程序員通常不用考慮它們。如果你感到對此好奇,可以查看qmetaobject類文檔和moc實現(xiàn)的c+代碼。-qws選項的含義是使這個應(yīng)用程序成為服務(wù)器。qt embedded也是一種c/s結(jié)構(gòu),需要有一個qt application做qws server,程序啟動時帶有-qws參數(shù)的就是qws server,不帶這個參數(shù)就是q

42、ws client。因此任何一個基于qt的application都可以做qws server。當(dāng)然qws server一定先于qws client啟動,否則qws client將啟動失敗。在實際應(yīng)用中,會指定某個特殊的application做qws server,這個application一般還會管理一些其它的系統(tǒng)資源。2.3快速設(shè)計對話框(rapid dialog design)2.3快速設(shè)計對話框通常程序員們都是用c+源代碼編寫qt應(yīng)用程序,qt也是很容易用來編寫的。然而,許多程序員更喜歡用可視化的方法設(shè)計對話框,這樣能更快速更容易對對話框進(jìn)行修改。qt designer滿足了程序員的這一

43、要求,提供了可視化設(shè)計對話框的方法。它可以給一個應(yīng)用程序提供全部或者部分對話框。用qt designer設(shè)計的對話框和用c+代碼寫成的對話框是一樣的,可以用做一個常用的工具,并不對編輯器產(chǎn)生影響。在這一節(jié)中,我們使用qt designer創(chuàng)建go-to-cell對話框,無論用編寫代碼的方式還是用qt designer,創(chuàng)建對話框都有如下基本的步驟:1、創(chuàng)建和初始化子控件。2、把子控件放到布局管理器中。3、設(shè)置tab順序。4、創(chuàng)建信號和槽。5、實現(xiàn)對話框的自己的槽函數(shù)。在windows平臺qt的安裝目錄的bin目錄下,點(diǎn)擊desinger.exe,或者在unix平臺,在命令行上輸入designe

44、r。當(dāng)qt designer啟動后,它會列出一個控件模板的列表,選擇一個模板,進(jìn)入設(shè)計。*原文中對qt designer的介紹略去不想翻譯了,只要稍有點(diǎn)界面編程基礎(chǔ)的都可以輕松使用。如果確實需要,以后再補(bǔ)上。我個人不喜歡使用這個東東,因為要多一個文件要維護(hù),當(dāng)然如果要頻繁修改所設(shè)計的對話框,那這種方法還是很方便的。但不管怎么樣,最終都要修改源代碼。所以我還是比較喜歡用源代碼的方式把控件手工寫出來。我想主要介紹把對話框設(shè)計好以后,保存為.ui文件后的處理。*假如設(shè)計好的文件保存在gotocell目錄中,命名為gotocelldialog.ui中,然后在同一個目錄下創(chuàng)建一個main.cpp文件,編

45、碼如下:#include #include #include ui_gotocelldialog.hint main(int argc, char *argv) qapplication app(argc, argv); ui:gotocelldialog ui; qdialog *dialog = new qdialog; ui.setupui(dialog); dialog-show(); return app.exec();保 存后,在該目錄下運(yùn)行qmake,創(chuàng)建.pro文件,然后運(yùn)行qmake -project生成makefile文件。qmake可以發(fā)現(xiàn)gotocelldialog.u

46、i文件,然后就會調(diào)用uic(qt的用戶界面編譯 器),uic工具把gotocelldialog.ui轉(zhuǎn)換成c+代碼,保存在ui_gotocelldialog.h中。在ui_gotocelldialog.h中,包含了ui:gotocelldialog類的定義,這個類和gotocelldialog.ui等價。這個類聲明成員變量存儲對話框的子控件和布局管理器,setupui()函數(shù)初始化對話框。這個類的定義看起來有點(diǎn)象下面這個樣子:class ui:gotocelldialogpublic: qlabel *label; qlineedit *lineedit; qspaceritem *space

47、ritem; qpushbutton *okbutton; qpushbutton *cancelbutton; . void setupui(qwidget *widget) . ;這個類沒有父類。使用時創(chuàng)建一個qdialog,把它傳遞給setupui()函數(shù)。運(yùn)行這個程序,對話框?qū)@示出來,但是有些功能它還不能實現(xiàn):1、ok按鈕是不可用狀態(tài)的2、cancel按鈕不作任何事情3、編輯框除可以輸入許可的字符或者數(shù)字外,還可以輸入任何文本我 們可以編寫代碼,讓這個對話框變得有用起來。最直接的方法是創(chuàng)建一個新類,繼承qdialog和ui:gotocell-dialog,補(bǔ)上缺少的功 能。(這說明

48、任何軟件問題可以通過添加一層間接包裝來簡單解決)。通常命名新類規(guī)則是把去掉uic生成的類名去掉ui:前綴。創(chuàng)建gotocelldialog.h頭文件,寫下如下代碼:#ifndef gotocelldialog_h#define gotocelldialog_h#include #include ui_gotocelldialog.hclass gotocelldialog : public qdialog, public ui:gotocelldialog q_objectpublic: gotocelldialog(qwidget *parent = 0);private slots: vo

49、id on_lineedit_textchanged();#endif新建gotocelldialog.cpp源文件,實現(xiàn)這個類:#include #include gotocelldialog.hgotocelldialog:gotocelldialog(qwidget *parent) : qdialog(parent) setupui(this); qregexp regexp(a-za-z1-90-90,2); lineedit-setvalidator(new qregexpvalidator(regexp, this); connect(okbutton, signal(click

50、ed(), this, slot(accept(); connect(cancelbutton, signal(clicked(), this, slot(reject();void gotocelldialog:on_lineedit_textchanged() okbutton-setenabled(lineedit-hasacceptableinput();在構(gòu)造函數(shù)中,我們調(diào)用setupui()初始化這個對話框。由于多繼承,我們可以直接使ui:gotocelldialog的成員。創(chuàng)建了用戶界面以后,我們可以把子控件的信號和槽函數(shù)連接起來。在 構(gòu)造函數(shù)中,我們還創(chuàng)建一個許可器(valid

51、ator)限制編輯框輸入的范圍。qt提供了三個許可器 類:qintvalidator,qdoublevalidator和qregexpvalidator。這里我們使用了 qregexpvalidator,使用的表達(dá)式為“a-za-z1-90-90,2”這個表達(dá)式的意思是第一個字符輸入為大寫或者小寫 字母,第二個字符為一個數(shù)字范圍是1到9,第三個字符是一個數(shù)字范圍為0到9。在qregexpvalidator的構(gòu)造函數(shù)中,第二個參數(shù)為this, 把當(dāng)前類作為它的父控件,這樣就可以不用刪除它,父控件析構(gòu)時可以被自動刪除。qt的父子機(jī)制在qobject中實現(xiàn)的。當(dāng)我們創(chuàng)建一個帶有父的 對象(如一個子控

52、件,一個許可器,布局管理器等)時,父對象把子對象放到自己的子對象列表中。父對象被刪除時,它查找自己的子對象并把每一個刪除掉。這些 子對象再把自己的子對象刪除掉,如此遞歸,知道刪除所有對象。這種父子對象的機(jī)制簡化了內(nèi)存管理,減少了內(nèi)存泄漏的危險。需要程序員刪除的對象就 是我們使用new創(chuàng)建的沒有父對象的對象。如果我們在父對象存在時刪除了它的一個子對象,qt將會在父列表中自動刪除。(需要記住的是qt只是刪除有父的 對象,父對象還是需要手動刪除的,還有就是那些用new申請的沒有指定父的內(nèi)存,一般情況下,在對話框里的子控件,許可器和布局管理器由qt自己管理,其 他還要程序員小心刪除)對于控件來講,父對

53、象還有一個意義:子控件在父對象的顯示區(qū)域內(nèi)顯示。當(dāng)父控件刪除后,子控件不但在內(nèi)存中被刪除,它也同時在屏幕上消失。在 構(gòu)造函數(shù)的最后兩行,把qdialog的accept()函數(shù)連接到ok按鈕的點(diǎn)擊信號,把cancel按鈕的點(diǎn)擊信號連接到reject()函數(shù)。這兩 個槽函數(shù)都關(guān)閉這個對話框,但是accept()返回 qdialog:accepted(值為1),reject()返回值為qdialog:rejected(值為0)。不同的返回值可以判斷用戶點(diǎn)擊 了那個按鈕。on_lineedit_textchanged()槽函數(shù)控制ok按鈕的可用狀態(tài),通過編輯框中的輸入字符,如果字符有效ok按鈕 則有效,否則為不可用狀態(tài)。qlineedit:hasac

溫馨提示

  • 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

提交評論