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