一.QPaintEvent绘图事件
QPaintEvent是QT中一个重要的类,专门用于绘图事件。当QT视图组件需要重绘制自己的一部分时,就会产生该事件,通常发生在以下几种情况。
- 窗口第一次显示时:当窗口或控件第一次出现在屏幕中,系统或窗口就会生成QPaintEvent事件,通知窗口进行自身的绘制
- 窗口大小改变时:当用户改变窗口的大小时,窗口中的内容通常需要重新绘制以适应新的尺寸
- 窗口部分被遮挡后又重新显示时:如果窗口被其他窗口遮挡,然后又重新露出来,被遮挡的部分通常需要重新绘制
- 手动请求重绘:通过调用QWidget的update()或repaint()方法,可以手动触发重绘事件。在Qt应用程序中,通常通过重写QWidget的paintEvent(QPaintEvent*)方法来处理绘制逻辑。
在Qt应用程序中,通常通过重写QWidget的paintEvent(QPaintEvent*)方法来处理绘制逻辑。
二.QPainter画家
2.1绘制基本图形
QPainter是Qt库中用于在屏幕上进行绘画的类。它提供了各种绘制功能,比如画线、画图形、画文本等。
1.初始化QPainter:首先,您需要一个QPaintDevice,比如一个QWidget或QPixmap,然后使用它来初始化QPainter对象。
QPainter painter(this); //假设在QWidget的子类中
2.设置画笔和画刷:您可以设置画笔(用于描边)和画刷(用于填充)的颜色、样式等。
/*QPen pen(Qt::green, 4);
painter.setPen(pen);*/painter.setPen(Qt::blue); //设置画笔颜色为蓝色
painter.setBrush(Qt::yellow); //设置画刷颜色为黄色(填充色)
painter.setRenderHint(QPainter::Antialiasing, true); //启用抗锯齿
painter.translate(rect().center()); //移动坐标原点至屏幕中央
painter.route(135); //旋转坐标系,正值代表顺时针painter.save(); //保存当前状态
painter.restore(); //与save函数配合使用,可恢复绘画师之前的状态
3.绘制图形:使用QPainter的方法来绘制线条、矩形、圆形、文本等。
painter.drawLine(10, 10, 100, 100); //1.画线
painter.drawLine(QLine(10, 10, 100, 100));
painter.drawLine(QPoint(10, 10), QPoint(100, 100));painter.drawRect(10, 10, 100, 100); //2.画矩形
painter.drawRect(QRect(10, 10, 100, 100));painter.drawText(10, 10, "Hello, Qt!"); //3.画文本
painter.drawText(QPoint(10,10), "Hello, Qt!");
//在屏幕正中央画文本
painter.drawText(rect().center(), "Hello, Qt!");painter.drawEllipse(QRect(10,10,100,100)); //4.在矩形区域内画圆形或椭圆
painter.drawEllipse(10,10,100,100);
painter.drawEllipse(QPoint(20,30), 80, 80);painter.drawRect(QRect(20,20,200,100)); //5.在矩形区域内画扇形
painter.drawPie(QRect(20,20,200,100), 45*16, 90*16);
painter.drawPie(QRect(20,20,200,100), -45*16, -90*16);
//第二个参数是起始角度,第三个参数是跨度
QT中是以1/16度为基本单位的,起始角度和跨度同时为正是逆时针绘制,同时为负是顺时针绘制
起始角度:0 跨度:180 起始角度:45 跨度:135 起始角度:0 跨度:360
2.2渐变色
1.线性渐变
QLinearGradient是Qt框架中用于创建线性渐变的类。线性渐变是一种从一个颜色平滑过渡到另一个颜色的效果,其变化沿着两个点之间的直线进行。这种渐变在图形用户界面设计中非常常见,用于添加深度、立体感或动态效果。
1. 创建 QLinearGradient 对象:指定渐变的起点和终点坐标。
从左上顶点到右下顶点进行渐变
QLinearGradient gradient(QPointF(10, 10), QPointF(50, 50));
从左边到右边进行渐变(图形的最左边的中间部分开始到最右边的中间部分结束)
QLinearGradient gradient(QPoint(100,110), QPoint(200, 110));
2. 设置颜色停靠点:在渐变线上定义颜色和相应的位置。可以设置多个颜色停靠点来创建更复杂的渐变效果.
// 设置颜色停靠点:在渐变线上定义颜色和相应的位置
gradient.setColorAt(0.0, Qt::red); // 起点颜色为红色
gradient.setColorAt(0.5, Qt::green); // 中间颜色为绿色
gradient.setColorAt(1.0, Qt::blue); // 终点颜色为蓝色
3. 使用渐变创建一个QPen(边框为渐变色)或QBrush(填充为渐变色),然后绘制图形
QPen pen;
pen.setBrush(gradient);
pen.setWidth(4); // 设置线条宽度
painter.setPen(pen);// 绘制渐变色边框的矩形
painter.drawRect(10, 10, 200, 200);
// 使用渐变创建 QPen
painter.setBrush(gradient);
painter.setPen(Qt::noPen());// 绘制渐变色边框的矩形
painter.drawRect(10, 10, 200, 200);
2.径向渐变
QRadialGradient是Qt框架中用于创建径向渐变的类。径向渐变是一种从中心点向外部辐射的颜色渐变,通常在中心点有一种颜色,而向外围渐渐变化为另一种颜色。这种渐变非常适合用于模拟光源、阴影或创建圆形的立体感。
1.创建QRadialGradient对象:指定渐变的中心点、半径以及焦点(可选)。
2.设置颜色停靠点:在径向渐变中定义颜色和对应的位置。
3.使用渐变创建QBrush:利用QRadialGradient对象创建一个QBrush,然后用它在QPainter中进行绘制。
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true); // 启用抗锯齿// 创建对象,设置中心点、半径和焦点(可选)
QRadialGradient gradient(rect().center(), 100);// 设置颜色停靠点:在径向渐变中定义颜色和对应的位置
gradient.setColorAt(0.0, QColor(255, 206, 232)); // 中间颜色淡粉色
gradient.setColorAt(1.0, QColor(255, 155, 170)); // 边缘为深粉色// 使用渐变创建 QBrush
painter.setBrush(gradient);
painter.drawEllipse(rect().center(), 100, 100); // 绘制圆形
3.圆锥形渐变
QConicalGradient是Qt框架中用于创建圆锥形渐变的类。圆锥渐变是一种渐变效果,其中颜色沿着圆锥的轮廓变化,类似于旋转颜色轮。这种渐变以其中心点为基点,颜色沿圆周分布,可以创建出富有动感的视觉效果。
在使用时,角度是按照顺时针方向测量的,起始点(0度)通常在三点钟方向。QConicalGradient非常适合用于创建旋转或动态效果的图形,例如加载指示器、进度条或任何需要圆周颜色变化的场景。
1. 创建 QConicalGradient 对象: 指定渐变的中心点和起始角度。
2. 设置颜色停靠点:为渐变添加不同的颜色和对应的位置(角度)。
3. 使用渐变创建 QBrush:使用这个渐变对象来创建一个 QBrush,然后应用到 QPainter 中进行绘图。
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true); // 启用抗锯齿// 1. 创建 QConicalGradient 对象:指定渐变的中心点和起始角度。
QConicalGradient gradient(width() / 2, height() / 2, 0);// 2. 设置颜色停靠点:为渐变添加不同的颜色和对应的位置(角度)。
gradient.setColorAt(0.0, QColor(255, 182, 193)); // 中心颜色为浅粉色
gradient.setColorAt(0.5, QColor(255, 160, 122)); // 中间颜色为浅橙色
gradient.setColorAt(1.0, QColor(173, 216, 230)); // 边缘颜色为浅蓝色
// 3. 使用渐变创建 QBrush:使用这个渐变对象来创建一个 QBrush,然后应用到 QPainter 中进行绘图。
painter.setBrush(gradient);
painter.drawEllipse(rect()); // 绘制圆形
三.实现仿雷达扫描
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QRadialGradient>
#include <QPainter>
#include <QTimer>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QTimer *timer = new QTimer(this);timer->setInterval(10); //设置定时时间为10msconnect(timer, &QTimer::timeout, this, [=](){ //当定时器超时时,激活绘画事件update();});timer->start(); //启动定时器
}void Widget::paintEvent(QPaintEvent *event)
{static int t = 0; //初始角度为0度if(t == 360){t = 0;}QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true); //启用抗锯齿QBrush brush(Qt::black);painter.setBrush(brush); //设置画刷为黑色painter.drawRect(rect()); //画矩形(黑色背景)painter.translate(rect().center()); //将坐标移动到屏幕正中央QPen pen(Qt::green, 4);painter.setPen(pen); //设置画笔颜色为绿色painter.setBrush(Qt::NoBrush); //丢掉画刷int R = height()/2/7; //圆的半径for(int i = 1; i <= 7; i++){ //画圆painter.drawEllipse(QPoint(0, 0), R*i, R*i);}painter.drawLine(QPoint(-R*7,0), QPoint(R*7,0)); //画横线painter.drawLine(QPoint(0,-R*7), QPoint(0,R*7)); //画竖线//设置锥形渐变// 1. 创建 QConicalGradient 对象:指定渐变的中心点和起始角度。QConicalGradient gradient(0, 0, t);// 2. 设置颜色停靠点:为渐变添加不同的颜色和对应的位置(角度)。gradient.setColorAt(0.0, QColor(0, 255, 0, 200));gradient.setColorAt(0.1, QColor(0, 255, 0, 100));gradient.setColorAt(0.2, QColor(0, 255, 0, 0));gradient.setColorAt(1, QColor(0, 255, 0, 0));// 3. 使用渐变创建 QBrush:使用这个渐变对象来创建一个 QBrush,然后应用到 QPainter 中进行绘图。painter.setBrush(gradient);painter.setPen(Qt::NoPen);painter.drawPie(QRect(-R*7,-R*7,R*2*7,R*2*7), t*16, 70*16); //画扇形t += 1;
}Widget::~Widget()
{delete ui;
}
四.实现简易的汽车仪表盘
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QRadialGradient>
#include <QPainter>
#include <QTimer>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QTimer *timer = new QTimer(this);timer->setInterval(50); //设置定时时间为10msconnect(timer, &QTimer::timeout, this, [=](){ //当定时器超时时,激活绘画事件update();});timer->start(); //启动定时器
}void Widget::paintEvent(QPaintEvent *event)
{static int anc = 0;if(anc == 270){t = 1;}else if(anc == 0){t = 0;}QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing, true); // 启用抗锯齿QBrush brush(Qt::black);painter.setBrush(brush); // 设置画刷为黑色painter.drawRect(rect()); // (1)画矩形(黑色背景)painter.translate(rect().center()); // 将坐标原点移动到屏幕正中央painter.setPen(Qt::NoPen);int bigR = height()/2; // 外圆的半径为高度的一半//设置径向渐变QRadialGradient gradient(QPoint(0,0), bigR);// 设置颜色停靠点:在径向渐变中定义颜色和对应的位置gradient.setColorAt(0.0, QColor(255, 0, 0, 100));gradient.setColorAt(1.0, QColor(255, 0, 0, 200));// 使用渐变创建 QBrushpainter.setBrush(gradient);painter.drawEllipse(QPoint(0,0), bigR, bigR); // (2)绘制外部圆形painter.setBrush(Qt::NoBrush);QPen pen(Qt::white, 4);painter.setPen(pen);painter.drawEllipse(QPoint(0,0), 60, 60); // (3)绘制内部圆形//最小刻度double angle = 270*1.0/50;//保存当前painter属性painter.save();painter.rotate(135); // 坐标系顺时针旋转135度(90度+45度)for(int i = 0; i <= 50; i++){ // (4)绘制刻度和数字if(i % 10 == 0){//左半部分的仪表盘上的数字需要将坐标轴翻转180度后显示(02变为20)if(i * angle <= 135){painter.drawLine(QPoint(bigR-30, 0), QPoint(bigR-3, 0));painter.rotate(180);painter.drawText(QPoint(-(bigR - 32), 5),QString::number(i));painter.rotate(-180);}else{painter.drawLine(QPoint(bigR-30, 0), QPoint(bigR-3, 0));painter.drawText(QPoint(bigR - 50, 5),QString::number(i));}}else{painter.drawLine(QPoint(bigR-20, 0), QPoint(bigR-3, 0));}if(i <= 49){painter.rotate(angle);}}//注意:此时的坐标轴x轴在50刻度位置//坐标系旋转回初始位置painter.restore();painter.rotate(135 + anc);painter.setPen(QPen(Qt::yellow, 4));//(5)画指针painter.drawLine(QPoint(60,0), QPoint(bigR-70, 0));//坐标系旋转回到135度painter.rotate(-anc);//此时坐标在135度位置painter.setBrush(QColor(85,0,255,100));painter.setPen(Qt::NoPen);//(6)画扇形,扇形起始角度始终为135度,跨度为0到270度painter.drawPie(QRect(-bigR+70,-bigR+70,bigR*2-140,bigR*2-140), 0, -anc*16);if(t == 0){anc += 2;}else{anc -= 2;}}Widget::~Widget()
{delete ui;
}