基础知识

  • 主要的三个类
    • QPainter
      • QWidget
      • QPixmap
      • QPicture
      • QPrinter
      • QOpenGLPaintDevice
    • QPainterDevice
    • QPainterEngine

三者关系图

QPainter
QPainEngine
QPaintDevice

基本绘制和填充

绘图系统由QPainter完成具体的绘制操作,QPainter可以绘制一切想要的图形,QPainter可以在继承自QPainterDevice类的任何对象上进行绘制操作

Qt 之图形(QPainter 的基本绘图) 看这里

绘制文字

可参考Qt 之图形(绘制文本)

代码

	QPainter painter(this);
	QRectF rect(10.0, 10.0, 380.0, 280.0);
	painter.setPen(Qt::red);
	painter.drawRect(rect);
	painter.setPen(Qt::blue);
	painter.setPen(Qt::blue);
	painter.drawText(rect, Qt::AlignHCenter, QStringLiteral("你好"));
	painter.drawText(rect, Qt::AlignLeft, QStringLiteral("左对齐"));
	painter.drawText(rect, Qt::AlignRight, QStringLiteral("右对齐"));
	painter.drawText(rect, Qt::AlignVCenter, QStringLiteral("中间左侧对齐"));
	painter.drawText(rect, Qt::AlignBottom, QStringLiteral("底部对齐"));
	painter.drawText(rect, Qt::AlignCenter, QStringLiteral("中间对齐"));
	painter.drawText(rect, Qt::AlignBottom | Qt::AlignRight, QStringLiteral("底部 | 右侧对齐"));

效果

在这里插入图片描述

绘制路径

详细看这里Qt 之图形(QPainterPath)

代码

	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing);
	painter.setPen(Qt::red);
	QPainterPath path;
	path.moveTo(50, 250);
	path.lineTo(50, 230);
	path.cubicTo(QPointF(105, 40), QPointF(115, 80), QPointF(120, 60));
	path.lineTo(130, 130);
	path.addEllipse(QPoint(130, 130), 30, 30);
	painter.setBrush(Qt::red);
	painter.drawPath(path);
	
	path.translate(200, 0);
	painter.setPen(Qt::darkBlue);
	painter.drawPath(path);

效果

在这里插入图片描述

绘制图像

四种常见的绘制图像的方法

在这里插入图片描述

代码

	QPainter painter;
	//绘制image
	QImage image(100, 100, QImage::Format_ARGB32);
	painter.begin(&image);
	painter.setPen(QPen(Qt::green, 3));
	painter.setBrush(Qt::yellow);
	painter.drawRect(10, 10, 60, 60);
	painter.drawText(10, 10, 60, 60, Qt::AlignCenter, QStringLiteral("QImage"));
	painter.setBrush(QColor(0, 0, 0, 100));
	painter.drawRect(50, 50, 40, 40);
	painter.end();

	//绘制pixmap
	QPixmap pix(100, 100);
	painter.begin(&pix);
	painter.setPen(QPen(Qt::green, 3));
	painter.setBrush(Qt::yellow);
	painter.drawRect(10, 10, 60, 60);
	painter.drawText(10, 10, 60, 60, Qt::AlignCenter, QStringLiteral("QPixmap"));
	painter.setBrush(QColor(0, 0, 0, 100));
	painter.drawRect(50, 50, 40, 40);
	painter.end();

	//绘制bitmap
	QBitmap bit(100, 100);
	painter.begin(&bit);
	painter.setPen(QPen(Qt::green, 3));
	painter.setBrush(Qt::yellow);
	painter.drawRect(10, 10, 60, 60);
	painter.drawText(10, 10, 60, 60, Qt::AlignCenter, QStringLiteral("QBitmap"));
	painter.setBrush(QColor(0, 0, 0, 100));
	painter.drawRect(50, 50, 40, 40);
	painter.end();

	//绘制picture
	QPicture picture;
	painter.begin(&picture);
	painter.setPen(QPen(Qt::green, 3));
	painter.setBrush(Qt::yellow);
	painter.drawRect(10, 10, 60, 60);
	painter.drawText(10, 10, 60, 60, Qt::AlignCenter, QStringLiteral("QPicture"));
	painter.setBrush(QColor(0, 0, 0, 100));
	painter.drawRect(50, 50, 40, 40);
	painter.end();


	painter.begin(this);
	painter.drawImage(50, 20, image);
	painter.drawPixmap(200, 20, pix);
	painter.drawPixmap(50, 170, bit);
	painter.drawPicture(200, 170, picture);

效果

在这里插入图片描述
在这里插入图片描述

双缓冲绘图

在这里插入图片描述### 代码
在头文件加入

private:
	QPixmap pix;
	QPixmap tempPix;
	QPoint startPoint;
	QPoint endPoint;

	//是否正在绘图的标志
	bool isDrawing;

protected:
	void mousePressEvent(QMouseEvent *event);
	void mouseMoveEvent(QMouseEvent *event);
	void mouseReleaseEvent(QMouseEvent *event);
	void paintEvent(QPaintEvent *event);

在cpp文件加入

void ch10_4_1::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton)
	{
		startPoint = event->pos();
		isDrawing = true;
	}
}

void ch10_4_1::mouseMoveEvent(QMouseEvent *event)
{
	if (event->button() & Qt::LeftButton){
		endPoint = event->pos();
		tempPix = pix;
		update();
	}
}

void ch10_4_1::mouseReleaseEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton){
		endPoint = event->pos();
		isDrawing = false;
		update();
	}
}

void ch10_4_1::paintEvent(QPaintEvent *event)
{
	int x = startPoint.x();
	int y = startPoint.y();
	int width = endPoint.x() - x;
	int height = endPoint.y() - y;
	QPainter painter;
	painter.begin(&tempPix);
	painter.drawRect(x, y, width, height);
	painter.end();
	painter.begin(this);
	painter.drawPixmap(0, 0, tempPix);
	if (! isDrawing)
	{
		pix = tempPix;
	}
}

其中的ch10_4_1为类名

这里先在临时缓冲区进行绘图,然后将其绘制到界面上,最后判断是否已经完成绘图,如果是,则将临时缓冲区内容复制到缓冲区中,这样就完成了整个矩形的绘制

如果想实现Windows桌面上的拖动鼠标出现的橡皮筋选择框,可以使用QRubberBand类来实现橡皮筋线。

效果显示

在这里插入图片描述

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐