QT源碼解析(一) QT建立窗口程序、消息循環和WinMain函數

 

QT源碼解析(一) QT建立窗口程序、消息循環和WinMain函數

分類: QT

版權聲明

請尊重原創做品。轉載請保持文章完整性,並以超連接形式註明原始做者「tingsking18」和主站點地址,方便其餘朋友提問和指正。windows

 

QT源碼解析(一) QT建立窗口程序、消息循環和WinMain函數app

QT源碼解析(二)深刻剖析QT元對象系統和信號槽機制eclipse

QT源碼解析(三)深刻剖析QT元對象系統和信號槽機制(續)函數

QT源碼解析(四)剖析Qt的事件機制原理oop

QT源碼解析(五)QLibrary跨平臺調用動態庫的實現post

QT源碼解析(六)Qt信號槽機制與事件機制的聯繫學習

QT源碼解析(七)Qt建立窗體的過程ui

QT源碼解析(八)Qt是如何處理windows消息的spa

QT源碼解析(九)解析QDateTime.net

 

 

使用QT也有一段時間了,有的時候須要跟蹤代碼到QT的源碼中去查找問題。在這裏我將記錄一下我跟蹤QT源碼學習到的一些知識。

 

個人開發環境是VC6.0+QT4.3.3。QT已經不爲VC6.0提供addin了,因此有的時候我也會使用EclipseCDT來編寫代碼,由於有了QT for Eclipse的plugin寫代碼會方便一些。

 

咱們在學習QT的時候,接觸的第一個程序就是下面的helloworld程序:

 

[cpp]  view plain copy
 
  1. #include <QApplication>  
  2. #include <QPushButton>  
  3.   
  4. int main(int argc, char *argv[])  
  5. {  
  6.     QApplication app(argc, argv);     
  7.     QPushButton hello("Hello world!");  
  8.     hello.resize(100, 30);    
  9.     hello.show();  
  10.     return app.exec();  
  11. }  

 

這個程序的做用不少手冊和文檔都已經講了,講的也都很細緻,很是不錯。

 

可是喜歡鑽研,深刻的童鞋也許開始注意了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

---------------------------------------------------------------------------

相關文章
相關標籤/搜索