QT-QPainter
- 1.QPainter画图
- 1.1 概述
- 1.1 QPainter设置
- 1.2 QPainter画线
- 1.3 QPainter画矩形
- 1.4 QPainter画圆
- 1.5 QPainter画圆弧
- 1.6 QPainter画扇形
- 2.QGradient
- 2.1 QLinearGradient线性渐变
- 2.2 QRadialGradient径向渐变
- 2.3 QConicalGradient锥形渐变
- 3.综合仿雷达
- 4.仪表盘
- 4.1初
- 4.2 正弦纠正刻度文字方向
- 4.3 终
1.QPainter画图
1.1 概述
坐标系为
QPainter是Qt 库中用于在屏幕上进行绘画的类。它提供了各种绘制功能,比如画线、画图形、画文本等。在使用QPainter之前,需要对QPaintEvent事件进行重写
1.1 QPainter设置
1.初始化QPainter painter(this);2.设置笔刷QPen pen(Qt::blue,7);painter.setPen(pen);painter.setRenderHints(QPainter::Antialiasing,true); //抗锯齿painter.setFont(QFont("Arial", 30));
1.2 QPainter画线
//画线-两点确定painter.drawLine(10,200,300,20);painter.drawLine(QLine(10,200,300,20));painter.drawLine(QPoint(10,200),QPoint(300,20));
1.3 QPainter画矩形
//画矩形// void drawRect(const QRectF &rectangle) QRectF浮点型QRect rectangle(20,100,200,100); painter.drawRect(rectangle);
// void drawRect(int x, int y, int width, int height)painter.drawRect(20,100,200,100);
// void drawRect(const QRect &rectangle)
1.4 QPainter画圆
//画圆形--在矩形区域画椭圆painter.drawEllipse(rectangle);painter.drawEllipse(rect().center(),200,100); //在整个窗口的中间,画一个宽200 高100的椭圆painter.drawEllipse(QPoint(80,500),80,80); //在yuan圆心的坐标点为(80,500)处画一个80*80的圆
1.5 QPainter画圆弧
绘制的弧由给定的矩形、起始角和伸缩脚定义。起始角和伸缩脚必须以1/16度表示,即一个完整的圆等于5760(16*360)。角的正值表示逆时针方向,角的负值表示顺时针方向零度在3点钟的位置。如://(x,y,width,height)--x,y为左上角起始点坐标QRect rectangle(200,100,200,150); painter.drawRect(rectangle);painter.drawArc(rectangle,30*16,120*16);//30 起始角,正值逆时针方向,负值顺时针方向//120 伸缩角
QRect rectangle(200,100,200,150);painter.drawRect(rectangle);painter.drawArc(rectangle,30*16,120*16);painter.drawArc(30,100,100,180,45*16,90*16);
1.6 QPainter画扇形
painter.drawPie(rectangle,30*16,120*16);
2.QGradient
QLinearGradient(const QPointF &start, const QPointF &finalStop)//渐变色起始点和终止点setColorAt(qreal position, const QColor &color)
2.1 QLinearGradient线性渐变
QPainter painter(this);//起始点宽的 x:1/3---2/3 y:1/2处QLinearGradient lineGradient(width()/3,height()/2,width()*2/3,height()/2);lineGradient.setColorAt(0.1,Qt::black); //用给定的颜色在给定的位置创建一个停止点,给定的位置必须在0到1之间。lineGradient.setColorAt(1,Qt::white);QBrush brush(lineGradient);painter.setBrush(brush);painter.drawRect(rect());
QPainter painter(this);//从左上角到右下角开始变QLinearGradient lineGradient(0,0,width(),height());lineGradient.setColorAt(0.1,Qt::black);lineGradient.setColorAt(1,Qt::white);QBrush brush(lineGradient);painter.setBrush(brush);painter.drawRect(rect());
QPainter painter(this);QLinearGradient lineGradient(0,0,width(),height());lineGradient.setColorAt(0.7,Qt::black);lineGradient.setColorAt(1,Qt::white);QBrush brush(lineGradient);painter.setBrush(brush);painter.drawRect(rect());
}
lineGradient.setColorAt(0,Qt::blue); lineGradient.setColorAt(0.4,Qt::red);lineGradient.setColorAt(0.7,Qt::black);lineGradient.setColorAt(1,Qt::white);0-0.4 :蓝红渐变0.4-0.7 :红黑渐变0.7-1 :黑白渐变
2.2 QRadialGradient径向渐变
//QRadialGradient(const QPointF ¢er, qreal radius, const QPointF &focalPoint)QPainter painter(this);QRadialGradient radialGradient(400,400,100); //400,400--中心点,100辐射半径radialGradient.setColorAt(0,Qt::white); //中心radialGradient.setColorAt(1,Qt::black); //边缘painter.setBrush(QBrush(radialGradient));painter.drawRect(200,300,400,200);
2.3 QConicalGradient锥形渐变
QPainter painter(this);QConicalGradient conicalGradient(400,400,0);// 添加颜色停靠点conicalGradient.setColorAt(0.0, Qt::red);conicalGradient.setColorAt(0.5, Qt::blue);conicalGradient.setColorAt(1.0, Qt::red);// 使用这个渐变创建 QBrushQBrush brush(conicalGradient);// 使用 QBrush 进行绘图painter.setPen(Qt::NoPen); //设置无边框painter.setBrush(brush);painter.drawRect(200,300,400,200);
3.综合仿雷达
#include "widget.h"
#include "ui_widget.h"#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);timer = new QTimer(this);connect(timer,&QTimer::timeout,this,[=](){startAngle += 30;if(startAngle >= 360){startAngle = 0;}update();});timer->setInterval(100);timer->start();
}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing,true); //平滑处理painter.setBrush(QBrush(Qt::black));painter.drawRect(rect()); //设置背景色被黑色painter.setBrush(Qt::NoBrush);painter.translate(rect().center()); //将坐标点转移到中间位置int rEve = height()/2/7;int dataTmp = rEve * 7;QPen pen(Qt::green,4); //设置画笔painter.setPen(pen);for(int i=1;i<=7;i++){painter.drawEllipse(QPoint(0,0),rEve*i,rEve*i);}painter.drawLine(-rEve*7,0,rEve*7,0); //横线painter.drawLine(0,-rEve*7,0,rEve*7); //竖线QConicalGradient conGradient(0,0,-startAngle); //中心点(0,0)起始角度30//设置锥形渐变色conGradient.setColorAt(0,QColor(0,255,0,200));conGradient.setColorAt(0.1,QColor(0,255,0,100));conGradient.setColorAt(0.2,QColor(0,255,0,0));conGradient.setColorAt(1,QColor(0,255,0,0));//用渐变色指定画刷painter.setBrush(conGradient);painter.setPen(Qt::NoPen); //取消边框//画扇形painter.drawPie(QRect(-dataTmp,-dataTmp,2*dataTmp,2*dataTmp),-startAngle*16,70*16);
}
4.仪表盘
4.1初
#include "widget.h"
#include "ui_widget.h"#include <QPainter>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);timer = new QTimer(this);currentValue = 0;connect(timer,&QTimer::timeout,[=](){if(mark == 0){currentValue++;if(currentValue >= 60){mark = 1;}}if(mark == 1){currentValue--;if(currentValue == 0){mark = 0;}}update();});timer->start(50);
}Widget::~Widget()
{delete ui;
}
void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing,true);//底色弄成黑色painter.setBrush(QBrush(Qt::black));painter.drawRect(rect());//坐标系平移到中心painter.translate(rect().center());//画大圆painter.drawEllipse(QPoint(0,0),height()/2,height()/2);painter.setBrush(Qt::NoBrush);//画小圆painter.setPen(QPen(Qt::white,3));painter.drawEllipse(QPoint(0,0),60,60);//当前值painter.setFont(QFont("华文宋体",10));painter.drawText(QRect(-60,-60,120,120),Qt::AlignCenter,QString::number(currentValue));//画刻度-旋转坐标轴画线//1.算出一个刻度需要旋转的角度double angle = 240.0 / 60.0;//2.设置第一个刻度的位置//顺时针旋转坐标轴到15度,会一直处在15度位置直到下一次旋转将在15基础上+再次旋转的角度painter.setFont(QFont("华文宋体",10));painter.save(); //保存旋转前的位置painter.rotate(150);for(int i = 0;i<=60;i++){if(i%5 == 0){//画字if(135+angle * i < 270){painter.rotate(180);painter.drawText(-(height()/2-30),10,QString::number(i*4));painter.rotate(-180);}else{painter.drawText(height()/2-70,10,QString::number(i*4));}//画长刻度painter.drawLine(height()/2-20,0,height()/2-3,0);}else{ //画短刻度painter.drawLine(height()/2-8,0,height()/2-3,0);}//画完后旋转painter.rotate(angle);}//画指针-线//坐标轴先回到原点painter.restore(); //恢复到原来位置painter.save();painter.rotate(150+ angle *currentValue);painter.drawLine(60,0,height()/2-50-20,0);//画扇形painter.restore();painter.setPen(Qt::NoPen);painter.setBrush(QColor(255,0,0,150));painter.drawPie(QRect(-height()/2,-height()/2,height(),height()),(360-150)*16,-angle*currentValue*16);//angle前取负数,为了让它顺时针方向画
}
4.2 正弦纠正刻度文字方向
1.如图下,红框中50所示,刻度线处的文字应当保持与50同样的方向而不是图中120的方向易知在不改变坐标系的情况下无理论怎么旋转,其在远处所写的字符都无法达到红框50所显示的字符易知通过50代替120可知,若将坐标系原点移到120处在修改字符50为120即可所以对于120的修改只需要在此坐标系的基础上将y轴的坐标改到120的坐标处即可2.那么它地方的坐标如何得到呢?已知条件1.圆的半径 r2.圆的偏转角度 a所以可得x,y的坐标x = r * cosa;y = r * sina;
//写刻度文字int r = height()/2- 45;for(int i=0;i<=60;i++){if(i%5 == 0){//保存坐标系painter.save();//算出平移点int delX = qCos(qDegreesToRadians(210-angle*i)) * r;int delY = qSin(qDegreesToRadians(210-angle*i)) * r;//平移坐标系painter.translate(QPoint(delX,-delY));//旋转坐标系//painter.rotate(angle * i); //已知120是正好的//写上文字painter.drawText(-20,-20,50,30, Qt::AlignCenter,QString::number(i*4));//恢复坐标系painter.restore();}}通过以上的修改,可将刻度转换成如下,但是只有120是正好的,其他的刻度需要先将坐标系旋转才能达到120的效果3.已知angle = 240.0 / 60.0 = 4在120处旋转角为0,所以其他位置的旋转角度只需要凑齐120度的旋转角度即可120刻度时旋转角度为0,已知,在120时 angle * i = 120,若想在此处旋转角度为0则:0 = angle * i - 120;所以其他位置应当旋转的角度为painter.rotate(angle * i - 120);
int r = height()/2- 50;for(int i=0;i<=60;i++){if(i%5 == 0){//保存坐标系painter.save();//算出平移点int delX = qCos(qDegreesToRadians(210-angle*i)) * r; //qt中认得是弧度,弧度=角度*pi/180int delY = qSin(qDegreesToRadians(210-angle*i)) * r;//平移坐标系painter.translate(QPoint(delX,-delY));//旋转坐标系painter.rotate(angle * i - 120);//写上文字painter.drawText(-25,-25,50,30, Qt::AlignCenter,QString::number(i*4));//恢复坐标系painter.restore();}}
4.3 终
#include "widget.h"
#include "ui_widget.h"#include <QPainter>
#include <QtMath>
#include <QDebug>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);setFixedSize(800,600); //设置默认窗口startAngle = 150;startSpeed();
}Widget::~Widget()
{delete ui;
}void Widget::initCanvas(QPainter& painter)
{painter.setRenderHint(QPainter::Antialiasing,true);//底色弄成黑色painter.setBrush(QBrush(Qt::black));painter.drawRect(rect());//坐标系平移到中心painter.translate(rect().center().x(),rect().center().y()+50);
}void Widget::drawMiddleCircle(QPainter &painter, int radius)
{//画小圆painter.setPen(QPen(Qt::white,3));painter.drawEllipse(QPoint(0,0),radius,radius);
}void Widget::drawCurrentSpeed(QPainter &painter)
{//当前值painter.setPen(Qt::white);QFont font("Arial",18);font.setBold(true); //加粗painter.setFont(font);painter.drawText(QRect(-60,-60,120,70),Qt::AlignCenter,QString::number(currentValue*4));QFont font2("Arial",10);font2.setBold(true); //加粗painter.setFont(font2);painter.drawText(QRect(-60,-60,120,160),Qt::AlignCenter,"Km/h");
}void Widget::drawScale(QPainter &painter,int radius)
{//1.算出一个刻度需要旋转的角度angle = 240.0 / 60.0;//2.设置第一个刻度的位置//顺时针旋转坐标轴到15度,会一直处在15度位置直到下一次旋转将在15基础上+再次旋转的角度painter.save(); //保存旋转前的位置painter.setPen(QPen(Qt::white,5));painter.rotate(startAngle);for(int i = 0;i<=60;i++){if(i>=40){painter.setPen(QPen(Qt::red,5));}if(i%5 == 0){//画长刻度painter.drawLine(radius-20,0,radius-3,0);}else{ //画短刻度painter.drawLine(radius-8,0,radius-3,0);}//画完后旋转painter.rotate(angle);}painter.restore();painter.setPen(QPen(Qt::white,5));
}void Widget::drawScaleText(QPainter &painter,int radius)
{QFont font("Arial",10);font.setBold(true); //加粗painter.setFont(font);int r = radius - 50;for(int i=0;i<=60;i++){if(i%5 == 0){//保存坐标系painter.save();//算出平移点int delX = qCos(qDegreesToRadians(210-angle*i)) * r; //qt中认得是弧度,弧度=角度*pi/180int delY = qSin(qDegreesToRadians(210-angle*i)) * r;//平移坐标系painter.translate(QPoint(delX,-delY));//旋转坐标系painter.rotate(angle * i - 120);//写上文字painter.drawText(-25,-25,50,30, Qt::AlignCenter,QString::number(i*4));//恢复坐标系painter.restore();}}
}void Widget::drawPointLine(QPainter &painter,int length)
{//坐标轴先回到原点painter.save();painter.setBrush(Qt::white);painter.setPen(Qt::NoPen);static const QPointF points[4] = {QPointF(0,0),QPointF(200,-1.0),QPointF(200.0,1.0),QPointF(0.0,15.0),};painter.rotate(startAngle + angle *currentValue);painter.drawPolygon(points,4);// painter.drawLine(60,0,length,0);painter.restore(); //恢复到原来位置
}void Widget::drawSpeedPie(QPainter &painter, int radius)
{painter.setPen(Qt::NoPen);painter.setBrush(QColor(255,0,0,80));painter.drawPie(QRect(-radius,-radius,radius*2,radius*2),(360-startAngle)*16,-angle*currentValue*16);//angle前取负数,为了让它顺时针方向画
}void Widget::startSpeed()
{timer = new QTimer(this);currentValue = 0;connect(timer,&QTimer::timeout,[=](){if(mark == 0){currentValue++;if(currentValue >= 61){mark = 1;}}if(mark == 1){currentValue--;if(currentValue == 0){mark = 0;}}update(); //更新});timer->start(50);
}void Widget::drawEllipseInnerBlack(QPainter &painter, int radius)
{painter.setBrush(Qt::black);painter.drawEllipse(QPoint(0,0),radius,radius);}void Widget::drawEllipseInnerShine(QPainter &painter, int radius)
{QRadialGradient radialGradient(0,0,radius);radialGradient.setColorAt(0,QColor(255,0,0,200));radialGradient.setColorAt(1,QColor(0,0,0,100));painter.setBrush(radialGradient);painter.drawEllipse(QPoint(0,0),radius,radius);
}void Widget::drawEllipseOuterShine(QPainter &painter, int radius)
{painter.setPen(Qt::NoPen);QRadialGradient radialGradient(0,0,radius);radialGradient.setColorAt(1,QColor(255,0,0,200));radialGradient.setColorAt(0.97,QColor(255,0,0,120));radialGradient.setColorAt(0.9,QColor(0,0,0,0));radialGradient.setColorAt(0,QColor(0,0,0,0));painter.setBrush(radialGradient);painter.drawPie(QRect(-radius,-radius,radius*2,radius*2),(360-150)*16,-angle*61*16);//angle前取负数,为了让它顺时针方向画
}void Widget::drawLogo(QPainter &painter, int radius)
{QRect rectangle(-40,radius*0.38,80,80);painter.drawPixmap(rectangle,QPixmap(":/icon.png"));
}
void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);int rad = height()/2;//初始化画布initCanvas(painter);//画小圆drawMiddleCircle(painter,60);//画刻度-旋转坐标轴画线drawScale(painter,rad);//写刻度文字drawScaleText(painter,rad);//画指针-线drawPointLine(painter,rad-70);//画扇形drawSpeedPie(painter,rad+22);//画渐变色内圈圆drawEllipseInnerShine(painter,110);//画黑色内圈drawEllipseInnerBlack(painter,80);//画当前速度drawCurrentSpeed(painter);//画外环发光圈drawEllipseOuterShine(painter,rad+22);drawLogo(painter,rad);
}
链接:https://pan.baidu.com/s/1UFuGa5WBCZv0H1BtSsIJbw
提取码:14wi
--来自百度网盘超级会员V5的分享