請尊重原創做品。轉載請保持文章完整性,並以超連接形式註明原始做者「tingsking18」和主站點地址,方便其餘朋友提問和指正。windows
QT源碼解析(一) QT建立窗口程序、消息循環和WinMain函數app
QT源碼解析(二)深刻剖析QT元對象系統和信號槽機制eclipse
QT源碼解析(三)深刻剖析QT元對象系統和信號槽機制(續)函數
QT源碼解析(五)QLibrary跨平臺調用動態庫的實現post
使用QT也有一段時間了,有的時候須要跟蹤代碼到QT的源碼中去查找問題。在這裏我將記錄一下我跟蹤QT源碼學習到的一些知識。
個人開發環境是VC6.0+QT4.3.3。QT已經不爲VC6.0提供addin了,因此有的時候我也會使用EclipseCDT來編寫代碼,由於有了QT for Eclipse的plugin寫代碼會方便一些。
咱們在學習QT的時候,接觸的第一個程序就是下面的helloworld程序:
這個程序的做用不少手冊和文檔都已經講了,講的也都很細緻,很是不錯。
可是喜歡鑽研,深刻的童鞋也許開始注意了int main(int argc, char *argv[]),這個main函數是標準的main函數,而windows應用程序的入口是winmain函數,而main函數是命令行程序的入口。win下窗口程序都有RegisterClass,和消息循環,QT是如何RegisterClass和建立消息循環的?
下面咱們未來一塊兒學習一下QT的源碼來解釋一下這個main函數和整個窗口程序的建立過程:
設置好路徑後,咱們先F10一下,看看這個程序究竟是從哪裏開始運行的。
程序跳到了/winmain/qtmain_win.cpp文件的WinMain函數中,再看這個文件上面的宏定義:#define main qMain
繼續看:在WinMain函數中調用了咱們本身定義的main函數:int result = main(argc, argv.data());
哇塞,原來如此啊。原來咱們寫的main函數是假的。哈哈。
再來看一下QT是如何建立窗體和消息循環的
首先咱們來到QApplication的構造函數:
QApplication::QApplication(int &argc, char **argv, int _internal)
: QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient))
{ Q_D(QApplication); d->construct(); QApplicationPrivate::app_compile_version = _internal;}
很明顯,首先調用的是QApplicationPrivate的構造函數。你們注意第三個參數:QApplication::Type type
這事Type類型的定義:enum Type { Tty, GuiClient, GuiServer };
下面是代碼註釋中對Type類型的解釋:
/enum QApplication::Type
/value Tty a console application
/value GuiClient a GUI client application
/value GuiServer a GUI server application (for Qt for Embedded Linux)
當程序運行到hello.show()的時候調用了QWidgetPrivate::create_sys函數。
在這裏咱們看到調用了相似RegisterClass的函數:QString windowClassName = qt_reg_winclass(q);
這裏的q是指向QWidget的指針(咱們先忽略掉這裏)。
以及包括後面的CreateWindow,ShowWindow等等咱們熟悉的WindowsAPI函數
const QString qt_reg_winclass(QWidget *w) 函數的原型是在qapplication_win.cpp中定義的。咱們轉到qt_reg_winclass函數的實現中。咱們就看到了windows的API函數RegisterClass和窗口消息處理函數:wc.lpfnWndProc = (WNDPROC)QtWndProc;
咱們看一下QtWndProc的實現,原來窗口消息都是在這裏進行處理的啊!
至於最後一句app.exec(); 調用了QCoreApplication的Exec函數,在這個函數中咱們看到了下面建立消息循環的代碼
QEventLoop eventLoop;
self->d_func()->in_exec = true;
int returnCode = eventLoop.exec();
在QCoreApplication.cpp中的註釋是這樣解釋的:
The application will enter
the event loop when exec() is called. exit() will not return
until the event loop exits, e.g., when quit() is called.
到這裏,main和WinMain函數究竟是怎麼回事,以及QT是怎麼建立窗口和消息循環的,咱們已經很是清楚了。
參考:http://blog.csdn.net/tingsking18/article/details/4737925
---------------------------------------------------------------------------