一、前言

柱状温度计控件,可能是很多人练手控件之一,基本上都是垂直方向展示,底部一个水银柱,中间刻度尺,刻度尺可以在左侧右侧或者两侧都有,自适应分辨率改动,有时候为了美观效果,可能还会整个定时器来实现动画效果,开启动画效果的缺点就是CPU占用会比较高,前阵子有个好友(贾文涛-涛哥)向我推荐了一个opengl绘制的开源东西,QNanoPainter,东西是个好东西,我个人的理解是直接封装了opengl绘制的qpainter,可以使得绘制全部走GPU,这样就可以大大减轻CPU的负担,非常方便,我自己试了下,方法和绘制逻辑和qpainter有点不一样,暂时没有将所有控件改成QNanoPainter版本,以后看情况吧。

二、实现的功能

  • 1:可设置精确度(小数点后几位)和间距
  • 2:可设置背景色/柱状颜色/线条颜色
  • 3:可设置长线条步长及短线条步长
  • 4:可启用动画及动画步长
  • 5:可设置范围值
  • 6:支持负数刻度值
  • 7:支持任意窗体大小缩放
  • 8:可设置柱状条位置 左侧 居中 右侧
  • 9:可设置刻度尺位置 无 左侧 右侧 两侧
  • 10:可设置用户设定目标值

三、效果图

在这里插入图片描述

四、头文件代码

#ifndef RULERTEMP_H
#define RULERTEMP_H

/**

  • 柱状温度计控件 作者:feiyangqingyun(QQ:517216493) 2016-11-4
  • 1:可设置精确度(小数点后几位)和间距
  • 2:可设置背景色/柱状颜色/线条颜色
  • 3:可设置长线条步长及短线条步长
  • 4:可启用动画及动画步长
  • 5:可设置范围值
  • 6:支持负数刻度值
  • 7:支持任意窗体大小缩放
  • 8:可设置柱状条位置 左侧 居中 右侧
  • 9:可设置刻度尺位置 无 左侧 右侧 两侧
  • 10:可设置用户设定目标值
    */

#include <QWidget>

#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,7,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif

class QDESIGNER_WIDGET_EXPORT RulerTemp : public QWidget
#else
class RulerTemp : public QWidget
#endif

{
Q_OBJECT
Q_ENUMS(BarPosition)
Q_ENUMS(TickPosition)

<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>double minValue READ getMinValue WRITE setMinValue<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>double maxValue READ getMaxValue WRITE setMaxValue<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>double value READ getValue WRITE setValue<span class="token punctuation">)</span>

<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>int precision READ getPrecision WRITE setPrecision<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>int longStep READ getLongStep WRITE setLongStep<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>int shortStep READ getShortStep WRITE setShortStep<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>int space READ getSpace WRITE setSpace<span class="token punctuation">)</span>

<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>bool animation READ getAnimation WRITE setAnimation<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>double animationStep READ getAnimationStep WRITE setAnimationStep<span class="token punctuation">)</span>

<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>bool showUserValue READ getShowUserValue WRITE setShowUserValue<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>double userValue READ getUserValue WRITE setUserValue<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>QColor userValueColor READ getUserValueColor WRITE setUserValueColor<span class="token punctuation">)</span>

<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>QColor bgColorStart READ getBgColorStart WRITE setBgColorStart<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>QColor bgColorEnd READ getBgColorEnd WRITE setBgColorEnd<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>QColor lineColor READ getLineColor WRITE setLineColor<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>QColor barBgColor READ getBarBgColor WRITE setBarBgColor<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>QColor barColor READ getBarColor WRITE setBarColor<span class="token punctuation">)</span>

<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>BarPosition barPosition READ getBarPosition WRITE setBarPosition<span class="token punctuation">)</span>
<span class="token function">Q_PROPERTY</span><span class="token punctuation">(</span>TickPosition tickPosition READ getTickPosition WRITE setTickPosition<span class="token punctuation">)</span>

public:
enum BarPosition {
BarPosition_Left = 0, //左侧显示
BarPosition_Right = 1, //右侧显示
BarPosition_Center = 2 //居中显示
};

<span class="token keyword">enum</span> TickPosition <span class="token punctuation">{</span>
    TickPosition_Null <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span>      <span class="token comment">//不显示</span>
    TickPosition_Left <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">,</span>      <span class="token comment">//左侧显示</span>
    TickPosition_Right <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">,</span>     <span class="token comment">//右侧显示</span>
    TickPosition_Both <span class="token operator">=</span> <span class="token number">3</span>       <span class="token comment">//两侧显示</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

explicit <span class="token function">RulerTemp</span><span class="token punctuation">(</span>QWidget <span class="token operator">*</span>parent <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">~</span><span class="token function">RulerTemp</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

protected:
void resizeEvent(QResizeEvent );
void paintEvent(QPaintEvent );
void drawBg(QPainter painter);
void drawBarBg(QPainter painter);
void drawRuler(QPainter painter, int type);
void drawBar(QPainter painter);
void drawValue(QPainter *painter);

private:
double minValue; //最小值
double maxValue; //最大值
double value; //目标值

int precision<span class="token punctuation">;</span>                  <span class="token comment">//精确度,小数点后几位</span>
int longStep<span class="token punctuation">;</span>                   <span class="token comment">//长线条等分步长</span>
int shortStep<span class="token punctuation">;</span>                  <span class="token comment">//短线条等分步长</span>
int space<span class="token punctuation">;</span>                      <span class="token comment">//间距</span>

bool animation<span class="token punctuation">;</span>                 <span class="token comment">//是否启用动画显示</span>
double animationStep<span class="token punctuation">;</span>           <span class="token comment">//动画显示时步长</span>

bool showUserValue<span class="token punctuation">;</span>             <span class="token comment">//显示用户设定值</span>
double userValue<span class="token punctuation">;</span>               <span class="token comment">//用户设定值</span>
QColor userValueColor<span class="token punctuation">;</span>          <span class="token comment">//用户设定值颜色</span>

QColor bgColorStart<span class="token punctuation">;</span>            <span class="token comment">//背景渐变开始颜色</span>
QColor bgColorEnd<span class="token punctuation">;</span>              <span class="token comment">//背景渐变结束颜色</span>
QColor lineColor<span class="token punctuation">;</span>               <span class="token comment">//线条颜色</span>
QColor barBgColor<span class="token punctuation">;</span>              <span class="token comment">//柱状背景色</span>
QColor barColor<span class="token punctuation">;</span>                <span class="token comment">//柱状颜色</span>

BarPosition barPosition<span class="token punctuation">;</span>        <span class="token comment">//柱状条位置</span>
TickPosition tickPosition<span class="token punctuation">;</span>      <span class="token comment">//刻度尺位置</span>

int barWidth<span class="token punctuation">;</span>                   <span class="token comment">//水银柱宽度</span>
int barHeight<span class="token punctuation">;</span>                  <span class="token comment">//水银柱高度</span>
int radius<span class="token punctuation">;</span>                     <span class="token comment">//水银柱底部圆半径</span>
int targetX<span class="token punctuation">;</span>                    <span class="token comment">//目标X坐标</span>
QRectF barRect<span class="token punctuation">;</span>                 <span class="token comment">//柱状区域</span>
QRectF circleRect<span class="token punctuation">;</span>              <span class="token comment">//底部圆区域</span>

bool reverse<span class="token punctuation">;</span>                   <span class="token comment">//是否倒退</span>
double currentValue<span class="token punctuation">;</span>            <span class="token comment">//当前值</span>
QTimer <span class="token operator">*</span>timer<span class="token punctuation">;</span>                  <span class="token comment">//定时器绘制动画</span>

private slots:
void updateValue();

public:
double getMinValue() const;
double getMaxValue() const;
double getValue() const;

int <span class="token function">getPrecision</span><span class="token punctuation">(</span><span class="token punctuation">)</span>              <span class="token keyword">const</span><span class="token punctuation">;</span>
int <span class="token function">getLongStep</span><span class="token punctuation">(</span><span class="token punctuation">)</span>               <span class="token keyword">const</span><span class="token punctuation">;</span>
int <span class="token function">getShortStep</span><span class="token punctuation">(</span><span class="token punctuation">)</span>              <span class="token keyword">const</span><span class="token punctuation">;</span>
int <span class="token function">getSpace</span><span class="token punctuation">(</span><span class="token punctuation">)</span>                  <span class="token keyword">const</span><span class="token punctuation">;</span>

bool <span class="token function">getAnimation</span><span class="token punctuation">(</span><span class="token punctuation">)</span>             <span class="token keyword">const</span><span class="token punctuation">;</span>
double <span class="token function">getAnimationStep</span><span class="token punctuation">(</span><span class="token punctuation">)</span>       <span class="token keyword">const</span><span class="token punctuation">;</span>

bool <span class="token function">getShowUserValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span>         <span class="token keyword">const</span><span class="token punctuation">;</span>
double <span class="token function">getUserValue</span><span class="token punctuation">(</span><span class="token punctuation">)</span>           <span class="token keyword">const</span><span class="token punctuation">;</span>
QColor <span class="token function">getUserValueColor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>      <span class="token keyword">const</span><span class="token punctuation">;</span>

QColor <span class="token function">getBgColorStart</span><span class="token punctuation">(</span><span class="token punctuation">)</span>        <span class="token keyword">const</span><span class="token punctuation">;</span>
QColor <span class="token function">getBgColorEnd</span><span class="token punctuation">(</span><span class="token punctuation">)</span>          <span class="token keyword">const</span><span class="token punctuation">;</span>
QColor <span class="token function">getLineColor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>           <span class="token keyword">const</span><span class="token punctuation">;</span>
QColor <span class="token function">getBarBgColor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>          <span class="token keyword">const</span><span class="token punctuation">;</span>
QColor <span class="token function">getBarColor</span><span class="token punctuation">(</span><span class="token punctuation">)</span>            <span class="token keyword">const</span><span class="token punctuation">;</span>

BarPosition <span class="token function">getBarPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span>    <span class="token keyword">const</span><span class="token punctuation">;</span>
TickPosition <span class="token function">getTickPosition</span><span class="token punctuation">(</span><span class="token punctuation">)</span>  <span class="token keyword">const</span><span class="token punctuation">;</span>

QSize <span class="token function">sizeHint</span><span class="token punctuation">(</span><span class="token punctuation">)</span>                <span class="token keyword">const</span><span class="token punctuation">;</span>
QSize <span class="token function">minimumSizeHint</span><span class="token punctuation">(</span><span class="token punctuation">)</span>         <span class="token keyword">const</span><span class="token punctuation">;</span>

public Q_SLOTS:
//设置最大最小值-范围值
void setRange(double minValue, double maxValue);
void setRange(int minValue, int maxValue);

<span class="token comment">//设置最大最小值</span>
<span class="token keyword">void</span> <span class="token function">setMinValue</span><span class="token punctuation">(</span>double minValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token function">setMaxValue</span><span class="token punctuation">(</span>double maxValue<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置目标值</span>
<span class="token keyword">void</span> <span class="token function">setValue</span><span class="token punctuation">(</span>double value<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token function">setValue</span><span class="token punctuation">(</span>int value<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置精确度</span>
<span class="token keyword">void</span> <span class="token function">setPrecision</span><span class="token punctuation">(</span>int precision<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置线条等分步长</span>
<span class="token keyword">void</span> <span class="token function">setLongStep</span><span class="token punctuation">(</span>int longStep<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token function">setShortStep</span><span class="token punctuation">(</span>int shortStep<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置间距</span>
<span class="token keyword">void</span> <span class="token function">setSpace</span><span class="token punctuation">(</span>int space<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置是否启用动画显示</span>
<span class="token keyword">void</span> <span class="token function">setAnimation</span><span class="token punctuation">(</span>bool animation<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//设置动画显示的步长</span>
<span class="token keyword">void</span> <span class="token function">setAnimationStep</span><span class="token punctuation">(</span>double animationStep<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置是否显示用户设定值</span>
<span class="token keyword">void</span> <span class="token function">setShowUserValue</span><span class="token punctuation">(</span>bool showUserValue<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置用户值</span>
<span class="token keyword">void</span> <span class="token function">setUserValue</span><span class="token punctuation">(</span>double userValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token function">setUserValue</span><span class="token punctuation">(</span>int userValue<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置用户设定值颜色</span>
<span class="token keyword">void</span> <span class="token function">setUserValueColor</span><span class="token punctuation">(</span><span class="token keyword">const</span> QColor <span class="token operator">&amp;</span>userValueColor<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置背景颜色</span>
<span class="token keyword">void</span> <span class="token function">setBgColorStart</span><span class="token punctuation">(</span><span class="token keyword">const</span> QColor <span class="token operator">&amp;</span>bgColorStart<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token function">setBgColorEnd</span><span class="token punctuation">(</span><span class="token keyword">const</span> QColor <span class="token operator">&amp;</span>bgColorEnd<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置线条颜色</span>
<span class="token keyword">void</span> <span class="token function">setLineColor</span><span class="token punctuation">(</span><span class="token keyword">const</span> QColor <span class="token operator">&amp;</span>lineColor<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置柱状颜色</span>
<span class="token keyword">void</span> <span class="token function">setBarBgColor</span><span class="token punctuation">(</span><span class="token keyword">const</span> QColor <span class="token operator">&amp;</span>barBgColor<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token function">setBarColor</span><span class="token punctuation">(</span><span class="token keyword">const</span> QColor <span class="token operator">&amp;</span>barColor<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置柱状条位置</span>
<span class="token keyword">void</span> <span class="token function">setBarPosition</span><span class="token punctuation">(</span><span class="token keyword">const</span> BarPosition <span class="token operator">&amp;</span>barPosition<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//设置刻度尺位置</span>
<span class="token keyword">void</span> <span class="token function">setTickPosition</span><span class="token punctuation">(</span><span class="token keyword">const</span> TickPosition <span class="token operator">&amp;</span>tickPosition<span class="token punctuation">)</span><span class="token punctuation">;</span>

Q_SIGNALS:
void valueChanged(double value);
};

#endif // RULERTEMP_H

五、核心代码

void RulerTemp::paintEvent(QPaintEvent *)
{
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

<span class="token comment">//绘制背景</span>
<span class="token function">drawBg</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>painter<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//绘制标尺及刻度尺</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>tickPosition <span class="token operator">==</span> TickPosition_Left<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">drawRuler</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>painter<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>tickPosition <span class="token operator">==</span> TickPosition_Right<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">drawRuler</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>painter<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>tickPosition <span class="token operator">==</span> TickPosition_Both<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">drawRuler</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>painter<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">drawRuler</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>painter<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">//绘制水银柱背景,包含水银柱底部圆</span>
<span class="token function">drawBarBg</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>painter<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//绘制当前水银柱,包含水银柱底部圆</span>
<span class="token function">drawBar</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>painter<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//绘制当前值</span>
<span class="token function">drawValue</span><span class="token punctuation">(</span><span class="token operator">&amp;</span>painter<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

void RulerTemp::drawBg(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
QLinearGradient bgGradient(QPointF(0, 0), QPointF(0, height()));
bgGradient.setColorAt(0.0, bgColorStart);
bgGradient.setColorAt(1.0, bgColorEnd);
painter->setBrush(bgGradient);
painter->drawRect(rect());
painter->restore();
}

void RulerTemp::drawBarBg(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(barBgColor);

int barX <span class="token operator">=</span> targetX <span class="token operator">-</span> barWidth <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">;</span>
int barY <span class="token operator">=</span> space<span class="token punctuation">;</span>
QRectF <span class="token function">barRect</span><span class="token punctuation">(</span>barX<span class="token punctuation">,</span> barY<span class="token punctuation">,</span> barWidth<span class="token punctuation">,</span> barHeight<span class="token punctuation">)</span><span class="token punctuation">;</span>

int circleX <span class="token operator">=</span> targetX <span class="token operator">-</span> radius<span class="token punctuation">;</span>
<span class="token comment">//偏移 2 个像素,使得看起来边缘完整</span>
int circleY <span class="token operator">=</span> <span class="token function">height</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> radius <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">;</span>
int circleWidth <span class="token operator">=</span> radius <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
QRectF <span class="token function">circleRect</span><span class="token punctuation">(</span>circleX<span class="token punctuation">,</span> circleY<span class="token punctuation">,</span> circleWidth<span class="token punctuation">,</span> circleWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>

QPainterPath path<span class="token punctuation">;</span>
path<span class="token punctuation">.</span><span class="token function">addRect</span><span class="token punctuation">(</span>barRect<span class="token punctuation">)</span><span class="token punctuation">;</span>
path<span class="token punctuation">.</span><span class="token function">addEllipse</span><span class="token punctuation">(</span>circleRect<span class="token punctuation">)</span><span class="token punctuation">;</span>
path<span class="token punctuation">.</span><span class="token function">setFillRule</span><span class="token punctuation">(</span>Qt<span class="token punctuation">:</span><span class="token punctuation">:</span>WindingFill<span class="token punctuation">)</span><span class="token punctuation">;</span>
painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span>
painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">restore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

void RulerTemp::drawRuler(QPainter *painter, int type)
{
painter->save();
painter->setPen(lineColor);

int barPercent <span class="token operator">=</span> barWidth <span class="token operator">/</span> <span class="token number">8</span><span class="token punctuation">;</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span>barPercent <span class="token operator">&lt;</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    barPercent <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">//绘制纵向标尺刻度</span>
double length <span class="token operator">=</span> <span class="token function">height</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">2</span> <span class="token operator">*</span> space <span class="token operator">-</span> <span class="token number">2</span> <span class="token operator">*</span> radius<span class="token punctuation">;</span>
<span class="token comment">//计算每一格移动多少</span>
double increment <span class="token operator">=</span> length <span class="token operator">/</span> <span class="token punctuation">(</span>maxValue <span class="token operator">-</span> minValue<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//长线条短线条长度</span>
int longLineLen <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
int shortLineLen <span class="token operator">=</span> <span class="token number">7</span><span class="token punctuation">;</span>

<span class="token comment">//绘制纵向标尺线 偏移 5 像素</span>
int offset <span class="token operator">=</span> barWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">;</span>

<span class="token comment">//左侧刻度尺需要重新计算</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>type <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    offset <span class="token operator">=</span> <span class="token operator">-</span>offset<span class="token punctuation">;</span>
    longLineLen <span class="token operator">=</span> <span class="token operator">-</span>longLineLen<span class="token punctuation">;</span>
    shortLineLen <span class="token operator">=</span> <span class="token operator">-</span>shortLineLen<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

double initX <span class="token operator">=</span> targetX <span class="token operator">+</span> offset<span class="token punctuation">;</span>
double initY <span class="token operator">=</span> space <span class="token operator">+</span> barPercent<span class="token punctuation">;</span>
QPointF <span class="token function">topPot</span><span class="token punctuation">(</span>initX<span class="token punctuation">,</span> initY<span class="token punctuation">)</span><span class="token punctuation">;</span>
QPointF <span class="token function">bottomPot</span><span class="token punctuation">(</span>initX<span class="token punctuation">,</span> <span class="token function">height</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">2</span> <span class="token operator">*</span> radius <span class="token operator">-</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">drawLine</span><span class="token punctuation">(</span>topPot<span class="token punctuation">,</span> bottomPot<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//根据范围值绘制刻度值及刻度值</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span>int i <span class="token operator">=</span> maxValue<span class="token punctuation">;</span> i <span class="token operator">&gt;=</span> minValue<span class="token punctuation">;</span> i <span class="token operator">=</span> i <span class="token operator">-</span> shortStep<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>i <span class="token operator">%</span> longStep <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">//绘制长线条</span>
        QPointF <span class="token function">leftPot</span><span class="token punctuation">(</span>initX <span class="token operator">+</span> longLineLen<span class="token punctuation">,</span> initY<span class="token punctuation">)</span><span class="token punctuation">;</span>
        QPointF <span class="token function">rightPot</span><span class="token punctuation">(</span>initX<span class="token punctuation">,</span> initY<span class="token punctuation">)</span><span class="token punctuation">;</span>
        painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">drawLine</span><span class="token punctuation">(</span>leftPot<span class="token punctuation">,</span> rightPot<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment">//绘制文字</span>
        QString strValue <span class="token operator">=</span> <span class="token function">QString</span><span class="token punctuation">(</span><span class="token string">"%1"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">arg</span><span class="token punctuation">(</span><span class="token punctuation">(</span>double<span class="token punctuation">)</span>i<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token string">'f'</span><span class="token punctuation">,</span> precision<span class="token punctuation">)</span><span class="token punctuation">;</span>
        double fontHeight <span class="token operator">=</span> painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">fontMetrics</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">height</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">if</span> <span class="token punctuation">(</span>type <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            QRect <span class="token function">textRect</span><span class="token punctuation">(</span>initX <span class="token operator">-</span> <span class="token number">45</span><span class="token punctuation">,</span> initY <span class="token operator">-</span> fontHeight <span class="token operator">/</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">drawText</span><span class="token punctuation">(</span>textRect<span class="token punctuation">,</span> Qt<span class="token punctuation">:</span><span class="token punctuation">:</span>AlignRight<span class="token punctuation">,</span> strValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>type <span class="token operator">==</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            QRect <span class="token function">textRect</span><span class="token punctuation">(</span>initX <span class="token operator">+</span> longLineLen <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">,</span> initY <span class="token operator">-</span> fontHeight <span class="token operator">/</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">,</span> <span class="token number">15</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">drawText</span><span class="token punctuation">(</span>textRect<span class="token punctuation">,</span> Qt<span class="token punctuation">:</span><span class="token punctuation">:</span>AlignLeft<span class="token punctuation">,</span> strValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span>
        <span class="token comment">//绘制短线条</span>
        QPointF <span class="token function">leftPot</span><span class="token punctuation">(</span>initX <span class="token operator">+</span> shortLineLen<span class="token punctuation">,</span> initY<span class="token punctuation">)</span><span class="token punctuation">;</span>
        QPointF <span class="token function">rightPot</span><span class="token punctuation">(</span>initX<span class="token punctuation">,</span> initY<span class="token punctuation">)</span><span class="token punctuation">;</span>
        painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">drawLine</span><span class="token punctuation">(</span>leftPot<span class="token punctuation">,</span> rightPot<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    initY <span class="token operator">+=</span> increment <span class="token operator">*</span> shortStep<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">restore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

void RulerTemp::drawBar(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(barColor);

<span class="token comment">//计算在背景宽度的基础上缩小的百分比, 至少为 2</span>
int barPercent <span class="token operator">=</span> barWidth <span class="token operator">/</span> <span class="token number">8</span><span class="token punctuation">;</span>
int circlePercent <span class="token operator">=</span> radius <span class="token operator">/</span> <span class="token number">6</span><span class="token punctuation">;</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span>barPercent <span class="token operator">&lt;</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    barPercent <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">if</span> <span class="token punctuation">(</span>circlePercent <span class="token operator">&lt;</span> <span class="token number">2</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    circlePercent <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">//标尺刻度高度</span>
double length <span class="token operator">=</span> <span class="token function">height</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">2</span> <span class="token operator">*</span> space <span class="token operator">-</span> <span class="token number">2</span> <span class="token operator">*</span> radius<span class="token punctuation">;</span>
<span class="token comment">//计算每一格移动多少</span>
double increment <span class="token operator">=</span> length <span class="token operator">/</span> <span class="token punctuation">(</span>maxValue <span class="token operator">-</span> minValue<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//计算标尺的高度</span>
int rulerHeight <span class="token operator">=</span> <span class="token function">height</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> <span class="token number">1</span> <span class="token operator">*</span> space <span class="token operator">-</span> <span class="token number">2</span> <span class="token operator">*</span> radius<span class="token punctuation">;</span>

int barX <span class="token operator">=</span> targetX <span class="token operator">-</span> barWidth <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">;</span>
int barY <span class="token operator">=</span> rulerHeight <span class="token operator">-</span> <span class="token punctuation">(</span>currentValue <span class="token operator">-</span> minValue<span class="token punctuation">)</span> <span class="token operator">*</span> increment<span class="token punctuation">;</span>
barRect <span class="token operator">=</span> <span class="token function">QRectF</span><span class="token punctuation">(</span>barX <span class="token operator">+</span> barPercent<span class="token punctuation">,</span> barY <span class="token operator">+</span> barPercent<span class="token punctuation">,</span> barWidth <span class="token operator">-</span> barPercent <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">,</span> barHeight <span class="token operator">+</span> radius <span class="token operator">-</span> barY<span class="token punctuation">)</span><span class="token punctuation">;</span>

int circleX <span class="token operator">=</span> targetX <span class="token operator">-</span> radius<span class="token punctuation">;</span>
<span class="token comment">//偏移 2 个像素,使得看起来边缘完整</span>
int circleY <span class="token operator">=</span> <span class="token function">height</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-</span> radius <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">-</span> <span class="token number">2</span><span class="token punctuation">;</span>
int circleWidth <span class="token operator">=</span> radius <span class="token operator">*</span> <span class="token number">2</span> <span class="token operator">-</span> circlePercent <span class="token operator">*</span> <span class="token number">2</span><span class="token punctuation">;</span>
circleRect <span class="token operator">=</span> <span class="token function">QRectF</span><span class="token punctuation">(</span>circleX <span class="token operator">+</span> circlePercent<span class="token punctuation">,</span> circleY <span class="token operator">+</span> circlePercent<span class="token punctuation">,</span> circleWidth<span class="token punctuation">,</span> circleWidth<span class="token punctuation">)</span><span class="token punctuation">;</span>

QPainterPath path<span class="token punctuation">;</span>
path<span class="token punctuation">.</span><span class="token function">addRect</span><span class="token punctuation">(</span>barRect<span class="token punctuation">)</span><span class="token punctuation">;</span>
path<span class="token punctuation">.</span><span class="token function">addEllipse</span><span class="token punctuation">(</span>circleRect<span class="token punctuation">)</span><span class="token punctuation">;</span>
path<span class="token punctuation">.</span><span class="token function">setFillRule</span><span class="token punctuation">(</span>Qt<span class="token punctuation">:</span><span class="token punctuation">:</span>WindingFill<span class="token punctuation">)</span><span class="token punctuation">;</span>
painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">drawPath</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//绘制用户设定值三角号</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>showUserValue<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>tickPosition <span class="token operator">==</span> TickPosition_Left <span class="token operator">||</span> tickPosition <span class="token operator">==</span> TickPosition_Both<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        QPolygon pts<span class="token punctuation">;</span>
        int offset <span class="token operator">=</span> <span class="token number">15</span><span class="token punctuation">;</span>
        double initX <span class="token operator">=</span> targetX <span class="token operator">-</span> <span class="token punctuation">(</span>barWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        double initY <span class="token operator">=</span> rulerHeight <span class="token operator">-</span> <span class="token punctuation">(</span>userValue <span class="token operator">-</span> minValue<span class="token punctuation">)</span> <span class="token operator">*</span> increment<span class="token punctuation">;</span>
        pts<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token function">QPoint</span><span class="token punctuation">(</span>initX<span class="token punctuation">,</span> initY<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        pts<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token function">QPoint</span><span class="token punctuation">(</span>initX <span class="token operator">-</span> offset<span class="token punctuation">,</span> initY <span class="token operator">-</span> offset <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        pts<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token function">QPoint</span><span class="token punctuation">(</span>initX <span class="token operator">-</span> offset<span class="token punctuation">,</span> initY <span class="token operator">+</span> offset <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">setBrush</span><span class="token punctuation">(</span>userValueColor<span class="token punctuation">)</span><span class="token punctuation">;</span>
        painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">drawPolygon</span><span class="token punctuation">(</span>pts<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">if</span> <span class="token punctuation">(</span>tickPosition <span class="token operator">==</span> TickPosition_Right <span class="token operator">||</span> tickPosition <span class="token operator">==</span> TickPosition_Both<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        QPolygon pts<span class="token punctuation">;</span>
        int offset <span class="token operator">=</span> <span class="token number">15</span><span class="token punctuation">;</span>
        double initX <span class="token operator">=</span> targetX <span class="token operator">+</span> <span class="token punctuation">(</span>barWidth <span class="token operator">/</span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        double initY <span class="token operator">=</span> rulerHeight <span class="token operator">-</span> <span class="token punctuation">(</span>userValue <span class="token operator">-</span> minValue<span class="token punctuation">)</span> <span class="token operator">*</span> increment<span class="token punctuation">;</span>
        pts<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token function">QPoint</span><span class="token punctuation">(</span>initX<span class="token punctuation">,</span> initY<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        pts<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token function">QPoint</span><span class="token punctuation">(</span>initX <span class="token operator">+</span> offset<span class="token punctuation">,</span> initY <span class="token operator">-</span> offset <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        pts<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span><span class="token function">QPoint</span><span class="token punctuation">(</span>initX <span class="token operator">+</span> offset<span class="token punctuation">,</span> initY <span class="token operator">+</span> offset <span class="token operator">/</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">setBrush</span><span class="token punctuation">(</span>userValueColor<span class="token punctuation">)</span><span class="token punctuation">;</span>
        painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">drawPolygon</span><span class="token punctuation">(</span>pts<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">restore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

void RulerTemp::drawValue(QPainter *painter)
{
painter->save();

QFont font<span class="token punctuation">;</span>
font<span class="token punctuation">.</span><span class="token function">setPixelSize</span><span class="token punctuation">(</span>circleRect<span class="token punctuation">.</span><span class="token function">width</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">0.55</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">setFont</span><span class="token punctuation">(</span>font<span class="token punctuation">)</span><span class="token punctuation">;</span>
painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">setPen</span><span class="token punctuation">(</span>Qt<span class="token punctuation">:</span><span class="token punctuation">:</span>white<span class="token punctuation">)</span><span class="token punctuation">;</span>
painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">drawText</span><span class="token punctuation">(</span>circleRect<span class="token punctuation">,</span> Qt<span class="token punctuation">:</span><span class="token punctuation">:</span>AlignCenter<span class="token punctuation">,</span> <span class="token function">QString</span><span class="token punctuation">(</span><span class="token string">"%1"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">arg</span><span class="token punctuation">(</span>currentValue<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

painter<span class="token operator">-</span><span class="token operator">&gt;</span><span class="token function">restore</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

六、控件介绍

  1. 超过150个精美控件,涵盖了各种仪表盘、进度条、进度球、指南针、曲线图、标尺、温度计、导航条、导航栏,flatui、高亮按钮、滑动选择器、农历等。远超qwt集成的控件数量。
  2. 每个类都可以独立成一个单独的控件,零耦合,每个控件一个头文件和一个实现文件,不依赖其他文件,方便单个控件以源码形式集成到项目中,较少代码量。qwt的控件类环环相扣,高度耦合,想要使用其中一个控件,必须包含所有的代码。
  3. 全部纯Qt编写,QWidget+QPainter绘制,支持Qt4.6到Qt5.12的任何Qt版本,支持mingw、msvc、gcc等编译器,支持任意操作系统比如windows+linux+mac+嵌入式linux等,不乱码,可直接集成到Qt Creator中,和自带的控件一样使用,大部分效果只要设置几个属性即可,极为方便。
  4. 每个控件都有一个对应的单独的包含该控件源码的DEMO,方便参考使用。同时还提供一个所有控件使用的集成的DEMO。
  5. 每个控件的源代码都有详细中文注释,都按照统一设计规范编写,方便学习自定义控件的编写。
  6. 每个控件默认配色和demo对应的配色都非常精美。
  7. 超过130个可见控件,6个不可见控件。
  8. 部分控件提供多种样式风格选择,多种指示器样式选择。
  9. 所有控件自适应窗体拉伸变化。
  10. 集成自定义控件属性设计器,支持拖曳设计,所见即所得,支持导入导出xml格式。
  11. 自带activex控件demo,所有控件可以直接运行在ie浏览器中。
  12. 集成fontawesome图形字体+阿里巴巴iconfont收藏的几百个图形字体,享受图形字体带来的乐趣。
  13. 所有控件最后生成一个dll动态库文件,可以直接集成到qtcreator中拖曳设计使用。
  14. 目前已经有qml版本,后期会考虑出pyqt版本,如果用户需求量很大的话。

七、SDK下载

  • SDK下载链接:https://pan.baidu.com/s/1A5Gd77kExm8Co5ckT51vvQ 提取码:877p
  • 下载链接中包含了各个版本的动态库文件,所有控件的头文件,使用demo,自定义控件+属性设计器。
  • 自定义控件插件开放动态库dll使用(永久免费),无任何后门和限制,请放心使用。
  • 目前已提供26个版本的dll,其中包括了qt5.12.3 msvc2017 32+64 mingw 32+64 的。
  • 不定期增加控件和完善控件,不定期更新SDK,欢迎各位提出建议,谢谢!
在这里插入图片描述
在这里插入图片描述

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐