一、導(dǎo)讀
把焦點(diǎn)回到Qt應(yīng)用開(kāi)發(fā)中,一般情況下,Qt應(yīng)用程序的本體由main.cpp文件中的main()函數(shù)中內(nèi)容描述:
#include#include"mainwindow.h" intmain(intargc,char*argv[]) { QApplicationapp(argc,argv); MainWindowwindow; window.show(); returnapp.exec(); }
在上述代碼中,創(chuàng)建了一個(gè)QApplication實(shí)例和MainWindow實(shí)例,MainWindow實(shí)例表示主窗體應(yīng)用,QApplication正是本文的描述對(duì)象,她是QWidget的“地基”。QApplication是專門(mén)的QGuiApplication,它具有一些基于QWidget應(yīng)用程序需要的功能:處理小部件特定的初始化和銷毀操作。文檔中對(duì)她是這樣描述的:
該類繼承自QGuiApplication類,文檔中對(duì)QGuiApplication是這樣描述的:
從上圖可知,QGuiApplication繼承自QCoreApplication,又來(lái)看看QCoreApplication類:
從上述描述可知,QApplication、QGuiApplication、QCoreApplication這三個(gè)類是“父-子”包含關(guān)系,那么在實(shí)際開(kāi)發(fā)中,該如何選擇呢?
對(duì)于任何基于QWidget的GUI應(yīng)用程序來(lái)說(shuō)(注意是基于QWidget的),無(wú)論該應(yīng)用程序在任何時(shí)間有多少個(gè)窗口,都只有一個(gè)QApplication對(duì)象;如果不是基于QWidget的GUI應(yīng)用程序,應(yīng)該使用QGuiApplication,例如QtQuick應(yīng)用,而對(duì)于不需要QWidget或者GUI的Qt應(yīng)用程序來(lái)說(shuō),應(yīng)該使用QCoreApplcation,該類不依賴于QtWidgets庫(kù)。在不需要GUI的應(yīng)用程序中,使用QCoreApplication,該類可以避免對(duì)圖形用戶界面所需的資源進(jìn)行不必要的初始化。
二、再談QApplication
在文本開(kāi)始處貼出的代碼中,main函數(shù)傳入的參數(shù)argc、argv在創(chuàng)建QApplication實(shí)例的時(shí)候傳了進(jìn)去,因?yàn)樵赒Application初始過(guò)程中需要用argv中的argc命令行參數(shù)構(gòu)造應(yīng)用程序?qū)ο?,從源碼角度看,在QApplication的構(gòu)造函數(shù)中會(huì)進(jìn)行如下操作:
上圖中,Q_D是一個(gè)宏定義,用于創(chuàng)建一個(gè)指向ApplicationPrivate的指針,定義如下:
#defineQ_D(Class)Class##Private*constd=d_func()
ApplicationPrivate類的存在用于描述QApplication的私有數(shù)據(jù),她的存在是為了Qt源碼而設(shè)計(jì)的?;氐絈Application的構(gòu)造函數(shù)中,最后會(huì)調(diào)用init(),該函數(shù)實(shí)現(xiàn)如下(/qtbase/src/widgets/kernel目錄中):
voidQApplicationPrivate::init() { #ifdefined(Q_OS_MACOS) QMacAutoReleasePoolpool; #endif //初始化QGuiApplication的私有數(shù)據(jù)。 QGuiApplicationPrivate::init(); //初始化資源。 initResources(); qt_is_gui_used=(application_type!=QApplicationPrivate::Tty); //處理命令行參數(shù)。 process_cmdline(); //Mustbecalledbeforeinitialize() QColormap::initialize();//初始化QColormap initializeWidgetPalettesFromTheme(); qt_init_tooltip_palette(); //初始化QApplication的私有數(shù)據(jù) QApplicationPrivate::initializeWidgetFontHash(); //初始化QApplication對(duì)象,重磅函數(shù) initialize(); eventDispatcher->startingUp(); #ifndefQT_NO_ACCESSIBILITY //factoryforaccessibleinterfacesforwidgetsshippedwithQt QAccessible::installFactory(&qAccessibleFactory); #endif }
從源碼角度,可以清楚地看到QApplication的構(gòu)造過(guò)程和功能,主要用于初始化與GUI相關(guān)的的資源,創(chuàng)建QApplication對(duì)象,有如下行為:
(1)使用我們的桌面設(shè)置(如palette()、font()和doubleClickInterval())來(lái)初始化應(yīng)用程序。并跟蹤這些屬性,以防止我們?nèi)值馗淖烂妫纾和ㄟ^(guò)某種控制面板。
(2)執(zhí)行事件處理,它從底層窗口系統(tǒng)接收事件并將它們分派到相關(guān)的小部件(可理解成一個(gè)事件中轉(zhuǎn)站)。通過(guò)使用sendEvent()和postEvent(),可以將自己的事件發(fā)送到小部件。
(3)解析常用的命令行參數(shù)并相應(yīng)地設(shè)置其內(nèi)部狀態(tài)。
(4)定義應(yīng)用程序的外觀,并封裝在QStyle對(duì)象中。當(dāng)然可以在運(yùn)行時(shí)使用setStyle()進(jìn)行更改。
(5)提供了通過(guò)translate()創(chuàng)建可見(jiàn)字符串的本地化操作。
(6)提供一些方便快捷的對(duì)象,便于在開(kāi)發(fā)中使用,例如desktop()和clipboard()。
(7)管理應(yīng)用程序的窗口。我們可以使用widgetAt()來(lái)詢問(wèn)哪個(gè)小部件位于某個(gè)位置,獲取topLevelWidgets()和closeAllWindows()的列表等。
(8)管理應(yīng)用程序的鼠標(biāo)指針處理。
在實(shí)際開(kāi)發(fā)中,可以通過(guò)instance()函數(shù)訪問(wèn)QApplication對(duì)象,該函數(shù)返回一個(gè)與全局qApp指針等價(jià)的指針。(qApp引用是應(yīng)用程序?qū)ο蟮奈ㄒ蝗种羔槨K葍r(jià)于QCoreApplication::instance(),但轉(zhuǎn)換為指向QApplication的指針,因此僅當(dāng)唯一的應(yīng)用程序?qū)ο笫荙Application時(shí)才有效),Qt源碼中qApp定義如下:
#defineqApp(static_cast(QCoreApplication::instance()))
三、結(jié)尾
QApplication就像QWidget的地基一樣,GUI中的界面控件就如同“磚塊”一樣碼在上面了。
最后,貼出參考文檔中給出的一份代碼,其實(shí)現(xiàn)背后的知識(shí)值得學(xué)習(xí):
QCoreApplication*createApplication(int&argc,char*argv[]) { for(inti=1;iapp(createApplication(argc,argv)); if(qobject_cast(app.data())){ //startGUIversion... }else{ //startnon-GUIversion... } returnapp->exec(); }
上述代碼演示了如何動(dòng)態(tài)創(chuàng)建適當(dāng)類型的應(yīng)用程序,小生從上述代碼get到一招和五個(gè)知識(shí)點(diǎn)......,打住,再寫(xiě)就跑題了。
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4327瀏覽量
62569 -
代碼
+關(guān)注
關(guān)注
30文章
4779瀏覽量
68521 -
應(yīng)用程序
+關(guān)注
關(guān)注
37文章
3265瀏覽量
57677 -
Qt
+關(guān)注
關(guān)注
1文章
302瀏覽量
37899
原文標(biāo)題:Qt的QApplication不簡(jiǎn)單!
文章出處:【微信號(hào):嵌入式小生,微信公眾號(hào):嵌入式小生】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論