目录
[3.1.1 绘制底色](#3.1.1 绘制底色)
[编辑 3.1.2 绘制大圆](#编辑 3.1.2 绘制大圆)
[3.3.4 绘制小圆的内容](#3.3.4 绘制小圆的内容)
[3.3.5 绘制表盘刻度和数字标注](#3.3.5 绘制表盘刻度和数字标注)
[3.3.6 绘制指针](#3.3.6 绘制指针)
[3.3.7 绘制扇形](#3.3.7 绘制扇形)
[3.2 设置定时器让表盘动起来](#3.2 设置定时器让表盘动起来)
[3.3.1 设置动态指针](#3.3.1 设置动态指针)
[3.2.2 更新扇形区域](#3.2.2 更新扇形区域)
1.简易雷达图思维导图
2.结果展示图
3.制作流程
3.1表盘的绘制
创建Qt ->widget下项目接口。
本示例使用的Qt 中的事件,所以,第一步重写 paintEvent()
widget.h 中添加
Widget.cpp 中添加
cpp
void Widget:: paintEvent(QPaintEvent *event){}
3.1.1 绘制底色
创建一个Qpainter 的类(this表明在最外面的窗口上绘制),同时alt+enter 导入头文件(不能导入,手动添加对应的头文件)
接下来设置抗锯齿,设置画刷颜色,最后绘制底层的矩形。
3.1.2 绘制大圆
首先明确Qt的坐标
painter.translate 将坐标图的原点移动某一点。
进行变换之后做一个径向渐变,作为画刷来绘制大圆的圆内色。 最后绘制大圆
painter.setBrush(Qt::NoBrush);表明在接下绘制的圆形的内部不进行颜色覆盖。保留和大圆相同的颜色,只绘制小圆的轮廓即可。
3.3.3绘制小圆
Qt中设置绘图时的画刷为无画刷,即不填充任何颜色或图案。这意味着在绘制图形时,不会使用画刷填充图形的内部,而只会绘制图形的轮廓。
通常情况下,当需要绘制只有轮廓而没有填充的图形时,可以使用 setBrush(Qt::NoBrush)
来设置画刷,以确保绘制的图形只有轮廓效果。
设置画刷和画笔,并进行绘制
3.3.4 绘制小圆的内容
在小圆内输入内容显示当前的速度,当然需要设置字体和brush ,最后使用drawText() ,其常用的构造函数有两个一个是,需要写字的(x,y) 和内容,另一个是输入一个QRect() ,在Rect内部中央进行书写。
3.3.5 绘制表盘刻度和数字标注
首先保留现在的坐标位置信息
painter.save() 和painter.restore() 。
接下来进行旋转135都。painter.rotate() 进行顺时针旋转。
蓝色坐标处。此时,我们已经找到了刻度开始的起点了。
从start 到end 一共(360-90)=270°。我们希望其可以均分未50分,所以每一份角度是double(270/50)=angle.
此时就可以绘制刻度了
使用drawline()
起始的坐标是大圆的半径就是(height/2-3,0) ,其中-3 是裕量,具体值根据调试微调。重点是(height/2-20,0) ,其中-20是未来显示刻度线出来,接下来painter.rotate(angle).循环50词即可。
接下里是数字标注,为了显示清晰,每10次显示一下标注。调用一下drawText
3.3.6 绘制指针
由于上面绘制刻度坐标信息打乱了,我希望角度位置信息恢复到rect.center() 状态。故使用
painter.restore() 恢复上调用painter.save()一个状态。
同时绘制指针。
3.3.7 绘制扇形
回到最原始的状态
3.2 设置定时器让表盘动起来
3.3.1 设置动态指针
需要设置定时器,在.h 定义,.cpp 实现(private 属性),并定义currentValue 用于显示当前的值。使用信号与槽,如果定时器时间到了,更新currentValue(paintEvent 里面很多draw 函数和currentValue 相关,更新了值画面也就动起来)。由于表盘达到最大会反方向运行,所以需要设定一给bool 值用于判定指针方向,完成之后,调用update() 更新painterEvent 就可以东起来。最后将启动定时器,即可。
3.2.2 更新扇形区域
同上。currentValue 更新即可。
3.3 完整代码
main.cpp
cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
Widget.h
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QTimer>
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
protected:
void paintEvent(QPaintEvent *event) override;
private:
Ui::Widget *ui;
int currentValue;
QTimer *timer;
int mark=0;
};
#endif // WIDGET_H
Widget.cpp
cpp
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>
#include<QRadialGradient>
#include <QPainter>
#include<QFont>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
currentValue=0;
timer=new QTimer();
connect(timer,&QTimer::timeout,[=](){
if(mark==0){
currentValue++;
if(currentValue>=51){
mark=1;
}
}
else if(mark==1){
currentValue--;
if(currentValue<=0){
mark=0;
}
}
update();
});
timer->setInterval(50);
timer->start();
}
Widget::~Widget()
{
delete ui;
}
void Widget:: paintEvent(QPaintEvent *event){
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(QBrush(Qt::black));
painter.drawRect(rect());
painter.translate(rect().center());
// qDebug()<<width()<<height();
QRadialGradient radialGradient(0,0,height()/2);
radialGradient.setColorAt(0.0,QColor(255,0,0,50));
radialGradient.setColorAt(1.0,QColor(255,0,0,250));
painter.setBrush(QBrush(radialGradient));
painter.setPen(Qt::white);
painter.drawEllipse(QPoint(0,0),height()/2,height()/2);
//
painter.setBrush(Qt::NoBrush);
QPen pen(Qt::white,3);
painter.setPen(pen);
painter.drawEllipse(QPoint(0,0),60,60);
painter.setFont(QFont("华文宋体",15));
painter.drawText(QRect(-60,-60,120,120),Qt::AlignCenter,QString::number(currentValue));
painter.save();
//旋转是按照顺时针进行旋转的从左到右进行旋转
painter.rotate(135);
double rotate=270*1.0/50;
for(int i=0;i<=50;i++){
if(i%10==0){
//在表盘的左侧,需要先将文字旋转180°,在进行写字,之后进行变换。
if(135+rotate*i<=270){
painter.rotate(180);
painter.drawText(-height()/2+25,7,QString::number(i));
painter.rotate(-180);
}
else{
//在 坐标x,y 进行写字绘图。 如果是构造函数是矩形的话,那么就在矩形 的内部进行绘图和构造。
painter.drawText(height()/2-50,7,QString::number(i));
}
}
painter.drawLine(height()/2-20,0,height()/2-3,0);
painter.rotate(rotate);
}
painter.restore();
painter.save();
painter.rotate(135+rotate*currentValue);
painter.drawLine(60,0,height()/2-55,0);
//绘制扇形
painter.restore();
painter.setPen(Qt::NoPen);
painter.setBrush(QColor(255,0,0,150));
QRect rectangle(-height()/2+58,-height()/2+58,height()-116,height()-116);
painter.drawPie(rectangle,(360-135)*16,-rotate*currentValue*16);
}
没有自定义ui,直接在原图上进行绘画.