QT-QPainter

 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 &center, 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);
    // 使用这个渐变创建 QBrush
    QBrush 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处在修改字符50120即可
	所以对于120的修改只需要在此坐标系的基础上将y轴的坐标改到120的坐标处即可
	2.那么它地方的坐标如何得到呢?
		已知条件
		1.圆的半径	r
		2.圆的偏转角度 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 = 4120处旋转角为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/180
            int 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/180
            int 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的分享
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值