【QT 5 相关实验-仪表盘-学习笔记-表盘组件练习与使用总结】
- 1、概述
- 2、实验环境
- 3、参考资料-致谢
- 4、自我提升+实验效果
- 5、代码练习-学习后拆解
- (1)头文件部分
- (2)绘制事件+绘制表盘代码
- (3) 每一块部分绘制
- 6、代码移植=提升类
- (1)布局控件
- (2)提升类细节
- (3)多个表盘设置值与代码设置值
- 7、本次实验样例代码
- 8、实验细节
- 9、总结
1、概述
最近因为要使用QT写个带表盘的界面,在上网找了相关资料后,质量其实有些参差不齐的,有的看的云里雾里的,有的也只是贴出来代码,真正执行起来时,对于我这种新手来说,还是有点莫不到头脑的。
所以我写文章习惯性将所有步骤罗列,将细节说明,也是因为整个流程大量细节,只要按照步骤来,一般能达到效果,但是如果你是针对某个问题感兴趣,那么整篇文章对你来说,文字又有点多,真是难以取舍文字应该写多写少啊~~!
2、实验环境
实验环境还是挺重要的,因为有时候,在你电脑上能运行的东西,在别人的电脑就不一定能运行,这一部分的原因就可能是实验版本不一样。
系统环境:window环境
QT软件版本:qt 5.14.2
3、参考资料-致谢
(1)上上周刚刚练习完的代码,这位博主写的不多,但是跟着练习完代码后,觉得代码仪表写的不错,我也是照着他这份代码进行练习的,这里肯定要说下的。
参考连接:https://blog.csdn.net/wojiaoanchao/article/details/104068188
(2)也尝试过过去其它样例代码,但是因效果,感觉不是很好,移植后指针老不在中心位置,也是自己开始很菜,尝试了很多方式调正都没有成功,所以后来就没有使用,不过对自己学习还是有帮助,还是觉定说下。
参考资料:https://www.voycn.com/article/qtzidingyiwidgetzhiyibiaopan
4、自我提升+实验效果
我自己跟着代码练习一遍,然后再输出出来,通过自己理解,复制了一个表盘,并且跟学习,总是要有些提高的,会讲有提升类相关的东西,并且尽量说清楚操作步骤。
实验效果如下
5、代码练习-学习后拆解
(1)头文件部分
这块是练习第一部分,建立一个空的例程后,添加新文件,如下图。
注意>>>从上图可以看到,虽然我们建立输入类名叫“GradientMeter”,但是文件名字分别是“gradientmeter.cpp”和"gradientmeter.h",两个都是小写的名字,但是提升类是,需要输入“GradientMeter”。
#ifndef GRADIENTMETER_H
#define GRADIENTMETER_H
#include <QWidget>
#include <QPropertyAnimation>
class GradientMeter : public QWidget
{
Q_OBJECT
Q_PROPERTY(double value READ getValue WRITE setValue)
Q_PROPERTY(int hShearValue READ getHShearValue WRITE setHShearValue)
Q_PROPERTY(int vShearValue READ getVShearValue WRITE setVShearValue)
Q_PROPERTY(double radiusInner READ getRadiusInner WRITE setRadiusInner)
Q_PROPERTY(double radiusOuter READ getRadiusOuter WRITE setRadiusOuter)
Q_PROPERTY(double radiusHalo READ getRadiusHalo WRITE setRadiusHalo)
Q_PROPERTY(QColor colorQuterFrame READ getColorOuterFrame WRITE setColorOuterFrame)
Q_PROPERTY(QColor colorInnerStart READ getColorInnerStart WRITE setColorInnerStart)
Q_PROPERTY(QColor colorInnerEnd READ getColorInnerStart WRITE setColorInnerEnd)
Q_PROPERTY(QColor colorOuterStart READ getColorOuterStart WRITE setColorOuterStart)
Q_PROPERTY(QColor colorOuterEnd READ getColorOuterEnd WRITE setColorOuterEnd)
Q_PROPERTY(QColor colorHaloStart READ getColorHaloStart WRITE setColorHaloStart)
Q_PROPERTY(QColor colorHaloEnd READ getColorHaloEnd WRITE setColorHaloEnd)
public:
explicit GradientMeter(QWidget *parent = nullptr);
~GradientMeter();
protected:
void paintEvent(QPaintEvent *event);
public:
GradientMeter();
private:
void drawOuterGradient(QPainter *painter);
void drawInnerGradient(QPainter *painter);
void drawOuterHalo(QPainter *painter);
void drawScale(QPainter *painter);
void drawScaleNum(QPainter *painter);
void drawPointer(QPainter *painter);
void drawPointerSector(QPainter *painter);
void drawValue(QPainter *painter);
void drawUnit(QPainter *painter);
private:
double value; //目标值
int hShearValue,vShearValue;//H、V扭曲值
double radiusInner; //渐变内圈外径
double radiusOuter; //渐变外圈内径
double radiusHalo; //光晕内半径
QColor colorOuterFrame; //表盘外边框压缩
QColor colorInnerStart; //渐变内圈起始颜色
QColor colorInnerEnd; //渐变内圈结束颜色
QColor colorOuterStart; //渐变外圈起始颜色
QColor colorOuterEnd; //渐变外圈结束颜色
QColor colorHaloStart; //光晕起始颜色
QColor colorHaloEnd; //光晕结束颜色
QPropertyAnimation *hShearAnimation,*vShearAnimation;
public:
double getValue() const;
int getHShearValue() const;
int getVShearValue() const;
double getRadiusInner() const;
double getRadiusOuter() const;
double getRadiusHalo() const;
QColor getColorOuterFrame() const;
QColor getColorInnerStart() const;
QColor getColorInnerEnd() const;
QColor getColorOuterStart() const;
QColor getColorOuterEnd() const;
QColor getColorHaloStart() const;
QColor getColorHaloEnd() const;
void setValue(int value);
void setValue(double value);
void setHShearValue(int value);
void setVShearValue(int value);
//表盘外边框颜色
void setColorOuterFrame(QColor color);
//内层渐变区半径
void setRadiusInner(int radius);
void setRadiusInner(double radius);
//外层渐变区半径
void setRadiusOuter(int radius);
void setRadiusOuter(double radius);
//外出光晕区半径
void setRadiusHalo(int radius);
void setRadiusHalo(double radius);
//内层渐变颜色
void setColorInnerStart(QColor color);
void setColorInnerEnd(QColor color);
//外出渐变颜色
void setColorOuterStart(QColor color);
void setColorOuterEnd(QColor color);
//光晕颜色
void setColorHaloStart(QColor color);
void setColorHaloEnd(QColor color);
void startShearAnimal(int duraiton,int hShearValue,int vShearValue);
public slots:
void updateValue(double value);
};
#endif // GRADIENTMETER_H
然后在"gradientmeter.h",我先手敲相关代码,为什么先练这部分?因为这部分,可以让你对全局函数有个相关框架认识。知道有什么函数以及相关变量声明。
(2)绘制事件+绘制表盘代码
之后是练习"gradientmeter.cpp"内相关代码,也是跟着编写完这块,对整个绘制有了框架的认识,如下图,可以明白,绘制表盘其实是一部分一部分绘制,每次绘制完成后,保存下,这下之前文章有提到练习绘制的那片文章就派上用场,有了地基,很多东西也就能看懂了。
之前铺垫文章:【QT 5 学习笔记-学习绘图相关+画线图形等+绘图事件+基础学习(1)】
之前铺垫文章:【QT 5 学习笔记-学习绘图相关+画图形图片等+绘图设备+基础学习(2)】
这部分主要代码:
void GradientMeter::paintEvent(QPaintEvent *event)
{
int width = this->width();
int height= this->height();
int side = qMin(width,height);
//绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing|QPainter::TextAntialiasing);
painter.translate(width/2,height/2);
painter.scale(side/200.0,side/200.0);
painter.shear(double(hShearValue/100.0f),double(vShearValue/100.0f));
//内层渐变
drawInnerGradient(&painter);
//外层渐变
drawOuterGradient(&painter);
//外层光晕
drawOuterHalo(&painter);
//刻度线
drawScale(&painter);
//刻度值
drawScaleNum(&painter);
//绘制指针
drawPointer(&painter);
//绘制扇形区域
drawPointerSector(&painter);
//绘制值
drawValue(&painter);
//绘制单位
drawUnit(&painter);
}
(3) 每一块部分绘制
那么接下来就是每个函数单独编写了,针对每个单独函数,我们需要了解到底是怎么画出来,就拿
第一个内次渐变来说,其实有点点像,先画个渐变颜色的圆,然后扣去一部分,对于整个仪表,一眼望过去,我们其实很难下手,不知道改真没做,但是反过来,使用基础图形一点点组起来,我们就很容易理解了。
//第三遍开始理解,是画了两个圆,大圆减去小圆
void GradientMeter::drawOuterHalo(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
QPainterPath smallCircle;
QPainterPath bigCircle;
float radius = radiusHalo;
smallCircle.addEllipse(-radius,-radius,radius * 2,radius * 2);
radius+=(100.0-radiusHalo);
bigCircle.addEllipse(-radius,-radius,radius * 2,radius * 2 );
//大圆刨去小圆部分
QPainterPath gradientPath = bigCircle - smallCircle;
QRadialGradient gradient(0,0,100,0,0);
gradient.setSpread(QGradient::ReflectSpread);
gradient.setColorAt(radiusHalo/100,colorHaloStart);
gradient.setColorAt(1,colorHaloEnd);
painter->setBrush(gradient);
painter->drawPath(gradientPath);
painter->restore();
}
6、代码移植=提升类
这个demo样例大概500多行代码,我觉得这已经非常少了,还是非常值得练习一下的。
到这里,认为代码部分就练习完毕了。
(1)布局控件
这篇文章还是有点高度,不是面对纯新手,基础的布局,会说下,但不会事无巨细,其实也可以看下面工程代码。
1)框架布局
2)设置滑动条范围
(2)提升类细节
1)控件选择提升类
2)输入需要提升类的名字,这里之前已经有了,直接选择就行。
这里需要注意的是,提升类的名称和类名一样,而不是文件名字一样。
(3)多个表盘设置值与代码设置值
因为我当时用了两个表盘,当时就有疑问,当我有两个以上表盘时,如何知道设置的是哪个值,该任何设置呢,这里其实因为提升类,相当这个控件能继承这个提升类,简单说,通过这个控件调用相关方法。
1)我们选择滑动条控件,转到槽
2)然后选择只要值改变,就触发这个槽函数
在这个函数里加入相关代码,控制表盘转动。
如上图这里通过控件就很好区分开了。
加完后,就可以运行,看相关结果了。
7、本次实验样例代码
样例代码:https://download.csdn.net/download/qq_22146161/87442462
8、实验细节
(1)表盘遇到问题,缩放与扩大时指针无法在中心。
我最开始其实跟着“3、参考资料-致谢”里面第二个样例学习的,但是移植后,发现表针总是不在中心,后续尝试了很多办法吧,都没能很好解决,所以才使用第一个样例。
(2)文字显示不全问题,或者没有一部分问题
如下图所示,当时移植文字没有显示全,这块中间垫一块东西就可以了。
(3)文字在不同分辨率屏幕显示不一样
这点经常遇到,自己暂时没有好的办法,一般都是根据要使用的屏幕进行适配,因为我这共有两个屏幕,分辨率又不一样,所以在一个屏幕上显示可以了,在另一个块,不一样可以如下图。
(4)代码打错,导致报相关不知道错误。
类似如下,大部分情况下,都是自己手敲代码错了,需要核对代码。
9、总结
整体看表盘,让我们去实现时,真的很难下手,不知道应该怎么去做,但是反过来,以组装的形式,将表盘拆解,我们就能窥探其精妙。