栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Qt 中使用 GDI+ 绘图

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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_OBJECT
public:
  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); 
}

运行结果如下:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/832665.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号