GUI 程序原理和实例分析

目录

1、GUI 程序原理分析

1、命令行应用程序

2、图形界面应用程序

3、图形界面程序 vs 命令行程序

2、GUI 程序实例分析

1、GUI程序开发原理 

2、GUI程序开发实例 

3、小结 

3、QT的本质

1、GUI用户界面元素

2、实例分析 

3、QT的本质 

4、Hello QT

4、小结


1、GUI 程序原理分析


1、命令行应用程序

命令行应用程序的特点(Command Line Interface) 

    - 是一种基于顺序执行结构的可执行程序 

    - 程序执行过程中不需要与用户产生交互 

    - 程序执行后给出最终的运行结果 

      编译过程中不产生用户交互,编译结束后或者生成可执行程序或者给出错误信包 

命令行应用程序的运行模式 

                    

                      程序的运行有固定的开始和固定的结束 

命令行应用程序适用于单任务场合、无交互或简单交互场合、服务器应用场合 

2、图形界面应用程序

图形界面应用程序的特点(Graphic User Interface) 

    - 是一种基于消息驱动模型的可执行程序 

    - 程序的执行依赖于用户的交互过程 

    - 程序执行过程中实时响应用户操作 

    - 一般情况下程序执行后不会主动退出(需要人为关闭)

图形界面应用程序的运行模式

                    

                    从main开始,定义主窗口,创建主窗口,创建主窗口中的

                    元素(按钮,菜单,工具栏),显示主窗口,进入一个消

                    息循环,等待操作系统给应用程序发消息

图形界面应用程序的消息处理模型

            

用户操作(鼠标,键盘),操作系统内核检测到用户的操作,根据操作生成一个系统消息(MSG),将消息发给

有焦点的应用程序的消息队列,消息循环从消息队列取出消息,调用消息处理函数处理对应消息

 

图形界面应用程序适用于 

    - 多任务的场合 

    - 强用户交互的场合 

    - 非专业计算机用户 

    - 图形界面应用程序是当代计

    - 算机系统中的主要程序类型。

3、图形界面程序 vs 命令行程序

                                                  当代大型软件产品架构模型

                

                                    我们往往用命令行应用程序开发后台应用程序

                                             用图形界面程序开发用户界面

                            图形界面程序和命令行程序是互补关系,并不是竞争关系

                

 

2、GUI 程序实例分析


1、GUI程序开发原理 

现代操作系统支持GUI界面 

               -现代操作系统提供原生SDK支持GUI程序开发

               -GUI程序开发是现代操作系统上的主流技术 

               -不同操作系统上的GUI开发原理相同 

               -不同操作系统上的GUI SDK不同 

GUI程序开发原理 

               -GUI程序在运行时会创建一个消息队列 

               -系统内核将用户操作翻译成对应的程序消息 

               -程序在运行过程中需要实时处理队列中的消息 

               -当队列中没有消息时,程序将处于停滞状态 

                                不同操作系统支持相同的GUI开发原理 

        

 

GUI程序开发的本质 

              -在代码中用程序创建窗口及窗口元素 

              -在消息处理函数中根据程序消息做出不同响应 

            

2、GUI程序开发实例 

多数操作系统以C函数的方式提供GUI SDK 

Windows操作系统为例 :

 

编程实验 

不了解Windows API的只需懂原理(看汉字)即可

GUI程序开发初体验   GUIDemo.sln 

这些自定义的函数实际内部调用的都是Windows操作系统提供给应用程序编程的接口(Windows API

分别转到定义地方

1、定义主窗口

                          内部调用的是RegisterClass函数,指定消息处理函数WndProc

                          消息处理函数内部调用的是系统提供的默认消息处理函数

2、创建主窗口

                          CreateWindow的调用

3、创建窗口中的元素

                          CreateWindow的调用

4、显示主窗口

                          ShowWindow,UpdateWindow的调用

5、进入消息循环

                          GetMessage,TranslateMessage,DispatchMessage

编译运行

                

 

关闭窗口,然而却发现

这是因为消息处理函数没有处理退出消息,只是调用的系统默认消息处理函数(可以正常最大化,最小化,拖拽等)

然而关闭窗口并不意味着退出(如迅雷,百度网盘),所以程序还在运行

可以通过增加消息处理代码解决

相应的增加相关消息处理代码,可对其它消息处理

即将消息映射到函数,编写相应消息处理函数(或者直接调用系统的相关消息处理函数)

结尾附完整代码

3、小结 

现代操作系统提供原生SDK支持GUI程序开发 

不同操作系统上的GUI SDK不同 

不同操作系统上的GUI开发原理相同 

GUI程序开发包括 

            -在代码中用程序创建窗口及窗口元素 

            -在消息处理函数中根据程序消息做出不同响应

3、QT的本质


1、GUI用户界面元素

GUI用户界面是由固定的窗口元素所构成的 

        

 

操作系统提供了创建用户界面元素所需要的函数 

各种功能不同的函数依次调用,从而创建出界面元素 

操作系统提供的原生函数无法直接映射到界面元素 

 

如何直观的将界面元素的概念直接映射到程序中? 

 

面向对象的GUI程序设计 

              - GUI应用程序是为解决非科学计算问题而诞生的,适用于非专业的日常生活领域 

              - 面向过程程序设计方法学不适合GUI程序设计 ,面向对象程序设计方法学更适合GUI程序设计

另一种眼界 

              - 用面向对象方法学看待GUI界面元素,所有的界面元素都可以看作实际的对象 

              - GUI用户界面是由各不相同的对象组成的 

                 主窗口对象 (组合)

                      •  菜单对象  

                      •  按钮对象 

                      •  文本框对象 

                      • ......

            GUI开发非常适合采用面向对象方法学 

                -将界面元素定义为对应的类 

                 - 通过抽象封装可以隐藏界面元素的细节 

                -程序的创建过程就是组合不同界面元素对象的过程

                    

操作系统只是提供创建用户界面所需函数,所以我们需要自己根据这些函数创建类,并且这些类可以复用

2、实例分析 

面向对象的方法创建GUI程序   GUIDemoEx.sln

直面理解:创建一个应用程序a,给a创建一个主窗口,主窗口下创建一个按钮,显示主窗口,进入消息循环

编译运行

下面分析他们是如何在背后调用系统提供的接口函数的

1、Application的定义文件

                        实际上Application封装了消息循环

2、转到MainWindow的声明

           发现继承了Widget类,再转到Widget类的声明

发现Widget不过是个抽象的概念,用来统一所有用户界面元素(即所有用户界面元素公共特性全部抽象到Widget里去了)

这样,我们就可以设计一个Widget类,所有用户界面元素类都从Widget继承而来

 

3、再看MainWindow定义文件

           构造函数就是用来创建一个主窗口对象即定义主窗口式样和创建主窗口

           MainWindow封装了定义主窗口式样函数创建主窗口函数显示窗口函数消息处理函数

4、查看PushButton声明

                            用户界面元素,继承Widget类,再看看PushButton定义

                 同样调用的系统提供的函数CreateWindow,且依赖于父窗口存在

 

                        我们手工开发这些界面元素类,需要大量时间精力,

                                那么如果已经有人开发了这些类呢?

3、QT的本质 

            QT是利用面向对象方法学开发的一套GUI组件库 

            QT将不同操作系统的GUI细节封装于类的内部 

            QT提供一套跨平台的类用于开发GUI程序 

            QT遵循经典的GUI应用程序开发模式 

4、Hello QT

QT是一套跨平台的GUI开发库 

QT是一套C++集成开发环境 

QT是一套开源的殿堂级架构技术教程 

 

第一个QT程序  Main.cpp

#include <QApplication>
#include <QMainWindow>
#include <QPushButton>

int main(int argc, char* argv[])
{
    QApplication a(argc, argv);
    QMainWindow w;
    QPushButton b(&w);
    
    b.setText("Hello QT!");
    
    w.show();
    
    return a.exec();
}

这是一个QT应用程序,我们发现和前面手工用面向对象方法写的GUI应用程序架构几乎一模一样,

证实了QT本质就是用面向对象方法学来封装操作系统所提供的与GUI开发相关的函数,让GUI开发变得非常简单直观

 

        通过命令行的方式编译QT源程序 

            -启动QT命令行 

             - 进入源程序所在目录 

             - 命令:

                    1. qmake -project     // 根据目录中的源码生成工程文件 

                    2. qmake     // 根据工程文件生成makefile文件 

                    3. make     // 根据makefile进行编译 

 

4小结

            GUI程序开发更适合采用面向对象方法学

            所有的界面元素都可以看作实际的对象 

            GUI用户界面是由各不相同的对象组成的 

            QT是利用面向对象方法学开发的一套GUI组件库 

            QT将GUI细节封装于类的内部,具有跨平台的特性 

QT是一套跨平台的C++界面开发库 

可以通过命令行的方式开发QT应用程序 

也可以通过QT Creator进行QT开发 

QT Creator同时支待Log调式法和断点调试法 

 

完整代码

MainForm.cpp

#include <windows.h>

#define STYLE_NAME    L"MainForm"
#define BUTTON_ID     919

/* 主窗口定义函数 */
BOOL DefineMainWindow(HINSTANCE hInstance);
/* 主窗口创建函数 */
HWND CreateMainWindow(HINSTANCE hInstance, wchar_t* title);
/* 主窗口内部元素创建函数 */
HWND CreateButton(HWND parent, int id, wchar_t* text);
/* 主窗口显示函数 */
HWND DisplayMainWindow(HWND hWnd, int nCmdShow);
/* 主窗口消息处理函数 */
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

static HWND MainWindow = NULL; // 主窗口句柄标

BOOL WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG Msg = {0};

    /* 1.自定义主窗口样式 */
    if( !DefineMainWindow(hInstance) )
    {
        return FALSE;
    }

    /* 2.创建主窗口 */
    MainWindow = CreateMainWindow(hInstance, STYLE_NAME);

    if( MainWindow )
    {
        /* 3.创建主窗口中的控件元素 */
        CreateButton(MainWindow, BUTTON_ID, L"My Button");

        /* 4.在屏幕上显示主窗口 */
        DisplayMainWindow(MainWindow, nCmdShow);
    }
    else
    {
        return FALSE;
    }

    /* 5.进入消息循环 */
    while( GetMessage(&Msg, NULL, NULL, NULL) )
    {
        /* 6.翻译并转换系统消息 */
        TranslateMessage(&Msg);
        /* 7.分发消息到对应的消息处理函数 */
        DispatchMessage(&Msg);
    }

    return TRUE;
}

BOOL DefineMainWindow(HINSTANCE hInstance)
{
    static WNDCLASS WndClass = {0}; // 系统结构体类型
                                    // 用于描述窗口样式
    WndClass.style         = 0;
    WndClass.cbClsExtra    = 0;
    WndClass.cbClsExtra    = 0;
    WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW);          // 定义窗口背景色
    WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);     // 定义鼠标样式
    WndClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION); // 定义窗口左上角图标
    WndClass.hInstance     = hInstance;                       // 定义窗口式样属于当前应用程序
    WndClass.lpfnWndProc   = WndProc;                         // 窗口消息处理函数
    WndClass.lpszClassName = STYLE_NAME;                      // 窗口样式名
    WndClass.lpszMenuName  = NULL;

    /* 将定义好的窗口式样注册到系统 */
    return RegisterClass(&WndClass);
}

HWND CreateMainWindow(HINSTANCE hInstance, wchar_t* title)
{
    HWND hwnd = NULL;

    hwnd = CreateWindow(STYLE_NAME,            // 通过定义好的窗口式样创建主窗口
                        title,                 // 主窗口标题
                        WS_OVERLAPPEDWINDOW,   // 创建后主窗口的显示风格
                        CW_USEDEFAULT,         // 主窗口左上角 x 坐标
                        CW_USEDEFAULT,         // 主窗口左上角 y 坐标
                        CW_USEDEFAULT,         // 主窗口宽度
                        CW_USEDEFAULT,         // 主窗口高度
                        NULL,                  // 父窗口
                        NULL,                  // 窗口菜单栏
                        hInstance,             // 主窗口属于当前应用程序
                        NULL);                 // 窗口参数

    return hwnd;

}

HWND DisplayMainWindow(HWND hWnd, int nCmdShow)
{
    ShowWindow(hWnd,nCmdShow); // 显示窗口
    UpdateWindow(hWnd);        // 刷新窗口

    return hWnd;
}

HWND CreateButton(HWND parent, int id, wchar_t* text)
{
    HINSTANCE hInstance = (HINSTANCE)GetWindowLong(parent, GWL_HINSTANCE);
    HWND hwnd = NULL;

    hwnd = CreateWindow(L"button",                               // 通过系统预定义式样创建窗口元素
                        text,                                    // 窗口元素标题
                        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,   // 窗口元素的显示风格
                        50,                                      // 窗口元素在窗口中的左上角 x 坐标
                        50,                                      // 窗口元素在窗口中的左上角 y 坐标
                        200,                                     // 窗口元素的宽度
                        60,                                      // 窗口元素的高度
                        parent,                                  // 窗口元素所在的父窗口
                        (HMENU)id,                               // 窗口元素 ID 值
                        hInstance,                               // 窗口元素属于当前应用程序
                        NULL);                                   // 窗口元素参数

	return hwnd;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	if ( message == WM_DESTROY )
	{
		PostQuitMessage(0);
	}
    /* 调用系统提供的默认消息处理函数 */
    return DefWindowProc(hWnd, message, wParam, lParam);
}

 

©️2020 CSDN 皮肤主题: 创作都市 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值