QT 원본 해석 (7) Qt 창을 만드는 과정

5281 단어

저작권 공지


본고는 오리지널 작품이므로 작가의 노동 성과를 존중해 주십시오.전재는 반드시 문장의 완전성을 유지하고 하이퍼링크 형식으로 원시 작가인'tingsking18'과 메인 사이트 주소를 밝혀 다른 친구들이 질문하고 바로잡는 데 편리하도록 해야 한다.
QT 원본 해석 (1) QT 창 프로그램 만들기, 메시지 순환, WinMain 함수
QT 원본 분석(二) QT 원본 대상 시스템과 신호 슬롯 메커니즘을 깊이 있게 분석한다.
QT 원본 분석 (3) QT 원본 대상 시스템과 신호 슬롯 메커니즘을 깊이 있게 분석(계속)
QT 원본 해석 (4) Qt의 이벤트 메커니즘 원리 분석
QT 원본 분석 (5) QLibrary 크로스플랫폼 호출 동적 라이브러리의 실현
QT 원본 해석 (6) Qt 신호 슬롯 메커니즘과 이벤트 메커니즘의 연계
QT 원본 해석 (7) Qt 창을 만드는 과정
QT 원본 해석 (8) Qt가 윈도우즈 메시지를 어떻게 처리하는지
QT 소스 해결(9) 해결QDateTime
앞에서 말한 바와 같이 Qt의 코드를 분석한 지 한참이 되었다. 예전에는 QT 원본 분석을 할 때 ue를 사용했다. 한 함수 이름은 QTDIR/src 디렉터리에서 반복적으로 찾은 다음에 함수 간의 호출 관계를 분석했는데 효율이 너무 낮았다. 최근에 더욱 간편한 방법이 하나 나왔다. 바로 Qt Creator라는 IDE를 이용하는 것이다.
이점은 다음과 같습니다.
1. Qt Creator는 코드의 호출을 쉽게 추적할 수 있어 코드를 분석하는 속도를 크게 높일 수 있다.
2. 함수 간의 호출 관계는 더욱 직관적으로 찾을 수 있다.
3. 코드의 세로 관계에 대한 파악이 편리하다.
나쁜 점:
1. 호출된 함수나 클래스의 관계만 보여준다.
2. 클래스, 특정한 그룹의 클래스, 함수 간의 관계에 대한 전체적인 파악이 부족하다.
QT 소스 해석에 사용한 방법을 요약하고 본론으로 들어갑니다.Qt 창을 만드는 과정은 linux에 익숙하지 않기 때문에 아래의 모든 분석은 윈도우즈를 기반으로 한 것입니다.
윈도우즈에서 API를 이용하여 창을 만드는 것에 대해 설명합니다.저는 여기서 더 이상 설명하지 않고 코드를 직접 제시한 다음에 아래의 코드와 결합하여 Qt가 창을 만드는 과정을 분석해 보겠습니다.
자세한 설명은 다음을 참조하십시오.
John Chen 황소의 블로그: WIN32 SDK 인터페이스 프로그래밍
 
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 프로그램을 작성합니다.
#include <QtGui/QApplication>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QPushButton w("hello kitty");
    w.show();
    return a.exec();
}

 
이 창 프로그램이 어떻게 만들어졌는지 분석해 봅시다.
먼저main 함수와winmain 함수에 관해서는 왜 Qt의 창 프로그램이winmain 함수가 아니라main 함수를 사용하는지 설명합니다. 제 또 다른 블로그에서 설명했습니다: QT 원본 해석 (1) QT 창 프로그램 만들기, 메시지 순환, Winmain 함수는 여기서 설명하지 않습니다.
윈도우 창은 반드시 RegisterClass라는 함수를 호출할 것입니다. QTDIR/src에서 검색해 보겠습니다. 두 개의 파일이 있는데 이 함수가 있습니다. 하나는 qapplicationwin.cpp 또 하나는 qeventdispatcherwin.cpp, 두 가지 작용이 다르니 이번에는 qapplicationwin.cpp의 RegisterClass 함수입니다. 이것은 창 생성과 관련이 있기 때문에 다음 QT 원본 해석 (8) Qt가 윈도우즈 메시지를 어떻게 처리하는지 qeventdispatcherwin.cpp의 RegisterClass 역할
우선 인터럽트를 qapplication 에 설정합니다.win.cpp의 qtreg_winclass 함수에서 디버깅을 시작하고 인터럽트까지 실행한 다음call stack은 다음과 같습니다.
다음 빨간색 상자는Call stack입니다. 함수 호출 순서를 볼 수 있습니다. QPush Button을 만드는 것은 show () 방법에서이고 show () 방법은 setVisible 방법을 사용합니다.
QtWndProc는 창의 리셋 함수로 RegisterClass에서 WNDCLASS 구조에 전달되며 QtWndProc는 위의 API와 창의 함수인 WndProc를 생성합니다.
QtWndProc의 코드를 살펴보자. 또한 switch (message) 이고, 한 무더기의case로 메시지를 처리한다. 마지막으로DefWindow Proc를 호출해서 그가 처리하지 않은 메시지를 시스템에 돌려보낸다.

좋은 웹페이지 즐겨찾기