> 文档中心 > Qt 中使用 GDI+ 绘图

Qt 中使用 GDI+ 绘图


背景

GDI+ 是 Windows 提供的图形设备接口 GDI 的后续版本,相比 GDI ,GDI+ 是面向对象的,使用更方便。
在 Qt 中也可以使用 GDI+ 进行绘图。

GDI+ 的使用

使用 GDI+ 进行绘图,需要引入相关的库文件以及头文件,并且进行 GDI+ 环境的初始化操作。
①.相关头文件及 lib 的引入

#include #include #pragma comment(lib, "Gdiplus.lib")using namespace Gdiplus;

②.GDI+ 的启动和关闭
在使用 GDI+ 绘图之前需要调用 GdiplusStartup 加载动态链接库 Gdiplus.dll 以对 GDI+进行初始化;在使用绘图结束后需要调用 GdiplusShutdown 卸载动态链接库以对 GDI+ 进行清除工作。

GdiplusStartupInput StartupInput;GdiplusStartup(&m_gdiplusToken, &StartupInput, NULL);//GDI+初始化//GdiplusShutdown(m_gdiplusToken);//GDI+ 清除

③.使用 RAII 管理 GDI+ 资源
定义一个类 GDIPlusHelper,把GDI+ 的启动和关闭操作分别写入类的构造和析构函数中,用来对 GDI+ 进行初始化和清理工作;然后在需要使用 GDI+ 绘图的 widget 中定义一个 GDIPlusHelper 成员即可。
GDIPlusHelper 类定义如下:

#pragma once#include #include #include #pragma comment(lib, "Gdiplus.lib")using namespace Gdiplus;class GDIPlusHelper : public QObject{  Q_OBJECT​public:  GDIPlusHelper(QObject *parent = nullptr)  {    GdiplusStartupInput StartupInput;    GdiplusStartup(&m_gdiplusToken, &StartupInput, NULL);//GDI+初始化  }  ~GDIPlusHelper()  {    GdiplusShutdown(m_gdiplusToken);//GDI+ 清除  }private:  unsigned long   m_gdiplusToken;//GDI+句柄};

Qt 中使用 GDI+ 操作

为在 Qt 中使用 gdi+ 进行绘图,需要以下操作:
①.设置 widget 属性

setAttribute(Qt::WA_PaintOnScreen);

②.重载 paintEngine 方法

QPaintEngine* paintEngine() const override { return nullptr; }

③.获取 HDC

HWND hwnd = (HWND)this->winId();//窗口句柄,标识窗口的唯一整数HDC hdc = GetDC(hwnd);//设备环境句柄

Qt 中使用 GDI+ 示例

①..h 文件

#pragma once#include #include "ui_LearnGDI.h"#include "GDIPlusHelper.h"class DemoGDI : public QWidget{  Q_OBJECTpublic:  DemoGDI(QWidget *parent = Q_NULLPTR);private:  Ui::LearnGDIClass ui;private:  GDIPlusHelper gdiHelper;protected:  QPaintEngine* paintEngine() const override { return nullptr; }  void paintEvent(QPaintEvent *event) override;//重绘事件private:  void DrawUser(HDC hdc);//绘图方法  };

②..cpp 文件

#include "LearnGDI.h"DemoGDI::DemoGDI(QWidget *parent)  : QWidget(parent){  ui.setupUi(this);  setAttribute(Qt::WA_PaintOnScreen);}void DemoGDI::paintEvent(QPaintEvent *event){  HWND hwnd = (HWND)this->winId();//窗口句柄,标识窗口的唯一整数  HDC hdc = GetDC(hwnd);//设备环境句柄    RECT widgetClientRect = { 0 };  GetClientRect(hwnd, &widgetClientRect);//获取窗口客户区坐标  int rectWidth = widgetClientRect.right - widgetClientRect.left;//客户区宽度  int rectHeight = widgetClientRect.bottom - widgetClientRect.top;//客户区高度    HDC memDc = CreateCompatibleDC(hdc);//创建和设备DC兼容的内存DC  HGDIOBJ memBmp = CreateCompatibleBitmap(hdc, rectWidth, rectHeight);//创建和设备DC兼容的内存位图  HGDIOBJ oldBmp = SelectObject(memDc, memBmp);//选择了位图才可以进行绘制  PatBlt(memDc, 0, 0, rectWidth, rectHeight, WHITENESS);//更改背景颜色,默认是黑色    DrawUser(memDc);//在内存DC上进行图像绘制BitBlt(hdc, 0, 0, rectWidth, rectHeight, memDc, 0, 0, SRCCOPY);//内存位图拷贝到设备SelectObject(memDc, oldBmp);//还原  DeleteObject(memBmp);  DeleteDC(memDc);  ReleaseDC(hwnd, hdc);  }void DemoGDI::DrawUser(HDC hdc){  Graphics graphics(hdc);   Pen pen(Color(255, 0, 255, 0),4);  graphics.DrawRectangle(&pen, 20, 20, 300, 100); }

运行结果如下:
在这里插入图片描述

在这里插入图片描述

Qt 中使用 GDI+ 绘图 阅读世界,共赴山海 Qt 中使用 GDI+ 绘图 423全民读书节,邀你共读