参考:https://blog.csdn.net/byxdaz/article/details/146278262
1. 概述

QPainter用于执行绘图操作,QPaintDevice(绘图设备)是二维空间的抽象,可以使用QPainter在其上绘制,QPaintEngine提供了画家在不同类型的设备上绘制的界面。QPaintEngine类由QPainter和QPaintDevice在内部使用,并且对应用程序程序员隐藏,除非他们创建自己的设备类型。
由以上描述可知,QPaintDevice是绘图设备,QPainter可以在QPaintDevice上绘图(即也可以在QPaintDevice的子类上绘图),QPaintEngine是内部使用的,可以不用管。
QPixmap QBitmap QImage QPicture这四个类都是QPaintDevice上的子类,所以可以使用QPainter在这四个类上绘制。
例如下代码是在QPixmap上绘制:
cpp
QPixmap pix(300, 300); //创建一个空的300*300的QPixmap
pix.fill(Qt::white); //填充颜色
QPainter painter(&pix); //创建一个在pix上绘制的painter
painter.setPen(QPen(Qt::green));
painter.drawEllipse(QPoint(50,50), 50, 50); //zai pix上画圆
pix.save(/*路径*/); //保存pix
2. 定义
QPixmap :专门为图像在屏幕上的显示做了优化,依赖操作系统绘图引擎,渲染效率高。
QBitmap :是 QPixmap 的一个子类,它的色深限定为 1(单色图像)。
QImage :专门为图像的像素级访问做了优化,例如可以使用setPixel(int x, int y, uint rgb)设置某个像素点的颜色。
QPicture :记录和重放 QPainter 绘图指令(如绘制路径、图形),存储为二进制绘图指令序列,不直接存储像素数据。
注意QPicture,它不像其他三个是存储像素数据的,它是存储绘图指令的,也就是painter执行的操作,例如下面代码:
cpp
// 保存QPicture
Widget::Widget(QWidget *parent) : QWidget(parent)
{
QPicture pic; //QPicture绘图设备,记录和重现绘图指令
QPainter painter; //创建painter
painter.begin(&pic); //在QPicture上绘制,实际上picture是将下面这些绘制指令记下来
painter.setPen(QPen(Qt::green)); //picture记录这条指令
painter.drawEllipse(QPoint(50,50), 50, 50); //picture记录这条指令
painter.end(); // 结束绘制
pic.save("drawing.pic"); //把picture保存为drawing.pic
}
// 重现QPicture命令
void PaintWidget::paintEvent(QPaintEvent *)
{
QPicture pic;
pic.load("D:\\drawing.pic"); //从drawing.pic加载picture绘制命令
QPainter painter;
painter.drawPicture(200, 200, pic); //将保存的绘图动作重新绘制到设备上
}
3. 区别

4. 适用场景
a) QImage
图像处理:滤镜、缩放、水印等需要直接操作像素的场景。
跨平台一致性:需确保不同操作系统下图像显示完全一致(如生成缩略图)。
多线程加载:在子线程中读取大尺寸图片,避免阻塞主线程。
b) QPixmap
界面显示:按钮图标、标签图片等高频渲染需求。
透明效果:支持带 Alpha 通道的 PNG 图片显示。
硬件加速:利用底层绘图引擎提升渲染性能(如动画)。
c) QBitmap
单色图形:黑白掩码、光标形状等场景。
轻量级资源:节省内存(如 UI 中的简单图标)。
d) QPicture
绘图指令复用:保存复杂绘图操作(如矢量图形),便于重复调用。
离线渲染:将绘图结果序列化为文件,支持后续编辑或传输。
5. 注意事项
颜色深度:QBitmap是1位单色位图,转换时需要处理颜色格式(如QImage::convertToFormat(QImage::Format_Mono))。
平台依赖:QPixmap在不同平台可能有不同底层实现(如X11或DirectFB),建议在主线程操作。
性能:QPicture存储的是绘图指令,转换为像素图(如QImage/QPixmap)需执行所有绘图命令,可能较慢。
线程安全:QPixmap和QBitmap不适合在非GUI线程操作,而QImage是线程安全的。
6. 优化建议
