zoukankan      html  css  js  c++  java
  • Qt创建窗体的过程

    版权声明

    本文为原创作品,请尊重作者的劳动成果。转载必须保持文章完整性,并以超链接形式注明原始作者“ tingsking18 ”和 主站点 地址,方便其他朋友提问和指正。

    QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数

    QT源码解析(二)深入剖析QT元对象系统和信号槽机制

    QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)

    QT源码解析(四)剖析Qt的事件机制原理

    QT源码解析(五)QLibrary跨平台调用动态库的实现

    QT源码解析(六)Qt信号槽机制与事件机制的联系

    QT源码解析(七)Qt创建窗体的过程

    QT源码解析(八)Qt是如何处理windows消息的

    QT源码解析(九)解析QDateTime

    前言:分析Qt的代码也有一段时间了,以前在进行QT源码解析的时候总是使用ue,一个函数名在QTDIR/src目录下反复的查找,然后分析函数之间的调用关系,效率实在是太低了,最近总结出一个更简便的方法,就是利用Qt Creator这个IDE。

    带来的好处是:

    1.       Qt Creator可以很方便的跟踪代码的调用,这样大大提高了分析代码的速度。

    2.       函数间的调用关系能更加直观的找到。

    3.       便于对代码的纵向关系的把握。

    带来的坏处:

    1.  只是展现了调用到的函数或者类的关系。

    2.  缺少对类、某一组类、函数间关系的整体把握。

    上面总结一下自己在QT源码解析时候用到的方法,下面开始步入正题。Qt创建窗体的过程,由于我对linux不是很熟悉,下面我所有的分析都是基于windows下的。

    关于windows下利用API创建窗体。我这里就不多解释了,直接给出代码,然后结合下面的代码来分析一下Qt创建窗体的过程。

    详细的解释请参考:

    John Chen大牛的博文:WIN32 SDK界面编程

    [cpp] view plaincopy
     
    1. #include <windows.h>  
    2. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;  
    3. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,  
    4.                     PSTR szCmdLine, int iCmdShow)  
    5. {  
    6.     static TCHAR szAppName[] = TEXT ("HelloWin") ;     
    7.       
    8.     HWND         hwnd ;  
    9.     MSG          msg ;  
    10.       
    11.     WNDCLASS     wc ;  
    12.     wc.style         = CS_HREDRAW | CS_VREDRAW ;  
    13.     wc.lpfnWndProc   = WndProc ;  
    14.     wc.cbClsExtra    = 0 ;  
    15.     wc.cbWndExtra    = 0 ;  
    16.     wc.hInstance     = hInstance ;  
    17.     wc.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;  
    18.     wc.hCursor       = LoadCursor (NULL, IDC_ARROW) ;  
    19.     wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;  
    20.     wc.lpszMenuName  = NULL ;  
    21.     wc.lpszClassName = szAppName ;  
    22.     if (!RegisterClass (&wc))  
    23.     {  
    24.         MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ;  
    25.         return 0 ;  
    26.           
    27.     }  
    28.     hwnd = CreateWindow (szAppName,                  // window class name  
    29.         TEXT (“hello”), // window caption  
    30.         WS_OVERLAPPEDWINDOW,        // window style  
    31.         CW_USEDEFAULT,              // initial x position  
    32.         CW_USEDEFAULT,              // initial y position  
    33.         CW_USEDEFAULT,              // initial x size  
    34.         CW_USEDEFAULT,              // initial y size  
    35.         NULL,                       // parent window handle  
    36.         NULL,                       // window menu handle  
    37.         hInstance,                  // program instance handle  
    38.         NULL) ;                     // creation parameters  
    39.     ShowWindow (hwnd, iCmdShow) ;  
    40.     UpdateWindow (hwnd) ;  
    41.     while (GetMessage (&msg, NULL, 0, 0))  
    42.     {  
    43.         TranslateMessage (&msg) ;  
    44.         DispatchMessage (&msg) ;  
    45.     }  
    46.     return msg.wParam ;  
    47.       
    48. }  
    49. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
    50. {  
    51.     HDC         hdc ;  
    52.     PAINTSTRUCT ps ;  
    53.     RECT        rect ;  
    54.     switch (message)  
    55.     {  
    56.     case WM_PAINT:  
    57.         hdc = BeginPaint (hwnd, &ps) ;  
    58.         GetClientRect (hwnd, &rect) ;  
    59.         DrawText (hdc, TEXT ("the WM_PAINTmessage"), -1, &rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;  
    60.         EndPaint (hwnd, &ps) ;  
    61.         return 0 ;  
    62.     case WM_DESTROY:  
    63.         PostQuitMessage (0) ;  
    64.         return 0 ;  
    65.     }  
    66.     return DefWindowProc (hwnd, message, wParam, lParam) ;  
    67. }  

    先写一个最简单的Qt程序:

    [cpp] view plaincopy
     
    1. #include <QtGui/QApplication>  
    2. #include <QPushButton>  
    3.   
    4. int main(int argc, char *argv[])  
    5. {  
    6.     QApplication a(argc, argv);  
    7.     QPushButton w("hello kitty");  
    8.     w.show();  
    9.     return a.exec();  
    10. }  

    来分析一下这个窗体程序是如何创建的。

    首先关于main函数和winmain函数,为什么Qt的窗口程序是用main函数而非winmain,在我的另外一篇博文中有解释:QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数 这里不再解释

    Windows窗体创建一定会调用RegisterClass这个函数的,我们在QTDIR/src里面搜索一下,有两个文件有这个函数一个是qapplication_win.cpp另外一个是qeventdispatcher_win.cpp,两个的作用不同,这次我们先研究qapplication_win.cpp中的RegisterClass函数,因为这个是与窗体创建有关的,下一篇QT源码解析(八)Qt是如何处理windows消息的 将会介绍qeventdispatcher_win.cpp中的RegisterClass的作用。

    我们先将断点设置在qapplication_win.cpp中的 qt_reg_winclass 函数里,然后开始调试,运行到断点,然后我们看一下call stack如下图:

    下面红色的框中为Call stack,我们可以看到函数调用的顺序,真正的创建QPushButton是在show()方法中,show()方法又调用了setVisible方法…… ……

    QtWndProc就是窗体的回调函数,在RegisterClass的时候传给WNDCLASS结构的,QtWndProc同上面的API创建窗体的函数WndProc。

    我们看一下QtWndProc的代码,也是一个switch (message) 然后一堆case来处理消息,最后也是调用DefWindowProc将不归他处理的消息交还给系统。

    参考:http://blog.csdn.net/tingsking18/article/details/5528666

  • 相关阅读:
    linux sysfs (2)
    微软——助您启动云的力量网络虚拟盛会
    Windows Azure入门教学系列 全面更新啦!
    与Advanced Telemetry创始人兼 CTO, Tom Naylor的访谈
    Windows Azure AppFabric概述
    Windows Azure Extra Small Instances Public Beta版本发布
    DataMarket 一月内容更新
    和Steve, Wade 一起学习如何使用Windows Azure Startup Tasks
    现实世界的Windows Azure:与eCraft的 Nicklas Andersson(CTO),Peter Löfgren(项目经理)以及Jörgen Westerling(CCO)的访谈
    正确使用Windows Azure 中的VM Role
  • 原文地址:https://www.cnblogs.com/findumars/p/4700251.html
Copyright © 2011-2022 走看看