用PS怎么做网站图片/站长工具网站排名
目录
1、命令行程序 vs 图形界面程序
2、GUI 程序原理与实例分析
3、QT的本质
1、命令行程序 vs 图形界面程序
命令行应用程序的特点(Command Line Interface)
-是一种基于顺序执行结构的可执行程序 , 程序执行过程中不需要与用户产生交互 ,程序执行后给出最终的运行结果
-编译过程中不产生用户交互,编译结束后或者生成可执行程序或者给出错误信包
-命令行应用程序适用于单任务场合、无交互或简单交互场合、服务器应用场合
-命令行应用程序的运行模式 : 程序的运行有固定的开始和固定的结束
图形界面应用程序的特点(Graphic User Interface)
-是一种基于消息驱动模型的可执行程序
-程序的执行依赖于用户的交互过程 ,程序执行过程中实时响应用户操作 ,一般情况下程序执行后不会主动退出(需要人为关闭)
-图形界面应用程序适用于 多任务的场合 ,强用户交互的场合 ,非计算机专业用户
-图形界面应用程序的运行模式
从main开始,定义主窗口,创建主窗口,创建主窗口中的元素(按钮,菜单,工具栏),显示主窗口,进入消息循环,等待操作系统给应用程序发消息
图形界面应用程序的消息处理模型
用户操作(鼠标,键盘),操作系统内核检测到用户的操作,根据操作生成一个系统消息(MSG),将消息发给有焦点的应用程序的消息队列,消息循环从消息队列取出消息,调用消息处理函数处理对应消息
图形界面程序 vs 命令行程序
往往用命令行应用程序开发后台应用程序,用图形界面程序开发用户界面, 图形界面程序和命令行程序是互补关系
2、GUI 程序原理与实例分析
GUI程序开发原理
-现代操作系统提供原生SDK支持GUI程序开发,GUI程序开发是现代操作系统上的主流技术
-不同操作系统上的GUI开发原理相同 ,不同操作系统上的GUI SDK不同
-系统内核将用户操作翻译成对应的程序消息 ,GUI程序在运行时会创建一个消息队列 ,程序在运行过程中需要实时处理队列中的消息 ,当队列中没有消息时,程序将处于停滞状态
不同操作系统支持相同的GUI开发原理
GUI程序开发的本质
-在代码中用程序创建窗口及窗口元素 ,在消息处理函数中根据程序消息做出不同响应
GUI程序开发实例
-多数操作系统以C函数的方式提供GUI SDK
-以Windows操作系统为例 :提供以下API用于开发界面程序
GUIDemo.sln (不了解Windows API的只需懂原理即可)
这些自定义的函数实际内部调用的都是Windows操作系统提供给应用程序编程的接口(Windows API),分别转到定义地方
1、定义主窗口:内部调用的是RegisterClass函数,指定消息处理函数为WndProc
消息处理函数内部调用的是系统提供的默认消息处理函数
2、创建主窗口: CreateWindow的调用
3、创建窗口中的元素:CreateWindow的调用
4、显示主窗口: ShowWindow,UpdateWindow的调用
5、进入消息循环:GetMessage,TranslateMessage,DispatchMessage
6、编译运行
关闭窗口,却发现
这是因为消息处理函数没有处理退出消息,只是调用的系统默认消息处理函数(可以正常最大化,最小化等)
然而关闭窗口只是没显示界面并不意味着退出,所以程序还在运行
可以通过增加消息处理代码解决,即将消息映射到函数,编写相应消息处理函数(或者直接调用系统的相关消息处理函数)
3、QT的本质
GUI用户界面是由固定的窗口元素所构成的
-操作系统提供了创建用户界面元素所需要的函数 ,各种功能不同的函数依次调用,从而创建出界面元素
-操作系统提供的原生函数无法直接映射到界面元素 ,不能直观的将界面元素的概念直接映射到程序中
-用面向对象方法学看待GUI界面元素,所有的界面元素都可以看作实际的对象
-GUI用户界面是由各不相同的对象组成的 。如 主窗口对象 组合 菜单对象 、 按钮对象、文本框对象
-操作系统只是提供创建用户界面所需函数,所以我们需要自己根据这些函数创建各种符合界面元素意义的类,并且这些类可以复用
-将界面元素定义为对应的类 ,通过抽象和封装可以隐藏界面元素的细节 , 程序的创建过程就是组合不同界面元素对象的过程
面向对象的方法创建GUI程序 GUIDemoEx.sln
表面理解:创建一个应用程序a,给a创建一个主窗口,主窗口下创建一个按钮,显示主窗口,进入消息循环
编译运行
下面分析他们是如何在背后调用系统提供的接口函数的
1、Application的定义文件:实际上封装了消息循环
2、转到MainWindow的声明
发现继承了Widget类,再转到Widget类的声明
发现Widget不过是个抽象的概念,用来统一所有用户界面元素(即所有用户界面元素公共特性全部抽象到Widget里去了)
这样,我们就可以设计一个Widget类,所有用户界面元素类都从Widget继承而来
3、再看MainWindow定义文件
构造函数就是用来创建一个主窗口对象即定义主窗口式样和创建主窗口
MainWindow封装了定义主窗口式样函数,创建主窗口函数,显示窗口函数,消息处理函数
4、查看PushButton声明
用户界面元素,继承Widget类,再看看PushButton定义
同样调用的系统提供的函数CreateWindow,且依赖于父窗口存在
手工开发这些界面元素类,需要大量时间精力,那么如果已经有人开发了这些类呢?
QT的本质
-QT是利用面向对象方法学开发的一套GUI组件库 ,QT将不同操作系统的GUI细节封装于类的内部 ,提供了一套跨平台的类用于开发GUI程序
-QT遵循经典的GUI应用程序开发模式 ,是一套跨平台的GUI开发库 ,是一套开源的殿堂级架构技术教程
第一个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进行编译
完整代码
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);
}