32.QT-製做最強電壓電阻錶盤,能夠自定義陰影效果,漸變顏色,圖標,文字標籤等-附帶demo程序

因爲上位機須要繪製電壓電阻錶盤,以下圖所示:html

後來,在網上找阿找,仍是沒找到滿意的,索性本身來畫控件算了,因爲第一次畫控件,因此花了我2天時間,才畫好ide

效果圖以下:函數

上圖的全部顏色(包括滑動的漸變/單一顏色,以及字體顏色)均可以自定義,包括圖標也能夠(上面的電阻圖標,網上沒找到好看的,因此很醜~)post

總體效果圖以下所示:測試

 該demo程序放在了提供的源碼地址裏了,下載好後,在子文件夾demo1裏面字體

介紹優化

代碼裏添加了自適應設置,根據窗口大小自動改變標籤,圖標,刻度值,中心圓數值等this

代碼裏集成了定時器,能夠經過setTimerType(int msec,int v)成員函數實現錶盤指針旋轉快慢,每過多少msec,跑多少值(v),若是msec=0或者v=0,則表示不用定時器,直接跳到終點。編碼

代碼裏經過setGradientColorMode(QList<QColor>& Qcolors)成員函數能夠自定義一組漸變顏色.url

也能夠經過setSingleColorMode(QColor color)成員函數自定義單一顏色(上圖2就是設置的單一顏色).

 

代碼介紹

1.代碼裏經過 painter類來繪圖,其中paintEvent()函數以下所示

void Dial::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setPen(Qt::NoPen);
    painter.setRenderHint(QPainter::Antialiasing,true);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);
    painter.translate(width()/2,height()/2);
    radius = qMin(width(),height())/2;
    centerR=radius*0.4;       //設置中心圓大小
    drawObkColor(painter);           //外圓盤
    drawScalebkColor(painter);      //畫刻度圓
    drawslideScaleColor(painter);   //畫劃過的顏色
    drawShade(painter);            //畫陰影
    drawScaleColor(painter);
    drawbkColor(painter);          //畫內圓
    drawScaleTextColor(painter);   //畫刻度值
    drawPointColor(painter);
    drawCenterColor(painter);      //繪製中心圓
    drawIconValueColor(painter);
    drawlabelColor(painter);
}

2.而後進入drawObkColor()函數,來繪畫外圓盤,函數以下所示

void Dial::drawObkColor(QPainter& paint)      //繪製外圓
{
        paint.save();
        QConicalGradient  Conical(0,0,90);
        Conical.setColorAt(0,oobkColor);
        Conical.setColorAt(0.5,oobkColor);
        Conical.setColorAt(0.12,oobkColor.darker(40));
        Conical.setColorAt(0.88,oobkColor.darker(40));
        Conical.setColorAt(0.4,oobkColor.darker(30));
        Conical.setColorAt(0.6,oobkColor.darker(30));
        Conical.setColorAt(0.25,oobkColor.darker(160));
        Conical.setColorAt(0.75,oobkColor.darker(160));
        Conical.setColorAt(1,oobkColor);
        paint.setBrush(Conical);
        paint.drawEllipse(QPointF(0,0), radius*0.96,radius*0.98);
        Conical.setAngle(270);
        Conical.setColorAt(0,obkColor.darker(40));
        Conical.setColorAt(0.5,obkColor.darker(40));
        Conical.setColorAt(0.25,obkColor.darker(160));
        Conical.setColorAt(0.75,obkColor.darker(160));
        paint.setBrush(Conical);
        paint.drawEllipse(QPointF(0,0), radius*0.93,radius*0.94);
        paint.restore();
}

外圓盤效果以下所示:

3.而後接下來開始畫刻度圓,畫了它後,才能開始畫刻度和劃過的顏色等

void Dial::drawScalebkColor(QPainter &paint)        //繪製刻度圓
{
    paint.save();
    paint.setBrush(bkColor);
    paint.drawEllipse(QPointF(0,0), radius*0.90,radius*0.90);

    paint.restore();
}

4.而後接下來開始畫劃過的顏色,就是上圖指針劃事後都會帶有顏色的那種 (以單色顏色爲例)

void Dial::drawslideScaleColor(QPainter &paint)    //畫劃過的顏色
{
    /*單一顏色*/  

    int Star_Angle= 210*16-(int)((value/(maxvalue-minvalue))*240*16);

    int spanAngle  =  210*16 - Star_Angle;

    if(spanAngle==0)
        return ;



    qreal SlideBottom =  ((qreal)radius*0.77)/((qreal)radius*0.90);    

    qreal SlideCenterTop = 1-(1-SlideBottom)/3;                        
    qreal SlideCenterBottom = SlideBottom+(1-SlideBottom)/3+0.01;      

    paint.save();

    QColor Tint_SlideColor = SingleSlideColor;


    QRadialGradient Radial(0,0,radius*0.90);


    Tint_SlideColor.setAlpha(40);
    Radial.setColorAt(1,Tint_SlideColor);
    Radial.setColorAt(SlideBottom-0.005,Tint_SlideColor);
    Radial.setColorAt(0,Qt::transparent);
    Radial.setColorAt(SlideBottom-0.006,Qt::transparent);


    Tint_SlideColor = SingleSlideColor;
    Tint_SlideColor.setAlpha(50);


    Radial.setColorAt(SlideCenterBottom-0.03,Tint_SlideColor);
    Radial.setColorAt(SlideCenterTop+0.03,Tint_SlideColor);

    Tint_SlideColor = SingleSlideColor;
    Tint_SlideColor.setAlpha(50);
    Radial.setColorAt(SlideCenterBottom-0.01,SingleSlideColor.darker(200));
    Radial.setColorAt(SlideCenterTop+0.01,SingleSlideColor.darker(200));

    Radial.setColorAt(SlideCenterBottom,SingleSlideColor);
    Radial.setColorAt(SlideCenterTop,SingleSlideColor);

    paint.setPen(Qt::NoPen);
    paint.setBrush(Radial);

    paint.drawPie(QRectF((qreal)-radius*0.90,(qreal)-radius*0.90,(qreal)radius*1.80,(qreal)radius*1.80),Star_Angle,spanAngle);

    paint.restore();
 


  //... ...  
   
}

效果:

5.而後接下來便開始畫刻度和刻度值,其中比較重要的就是繪製刻度值

因爲Painter的rotate()旋轉文字時,也會將文字傾斜了,因此咱們須要自定義rotate()函數

具體參考我另外一篇rotate函數分析:    31.QPainter-rotate()函數分析-文字旋轉不傾斜,圖片旋轉實現等待

 

drawScaleTextColor()畫刻度值函數以下所示:

void Dial::drawScaleTextColor(QPainter &paint)    //繪製刻度值
{
    /*繪製文字刻度*/
    paint.save();

    paint.setPen(ScaleColor);

    QString text("%1");

    int size;           //動態計算文字大小

    if(radius<=120)
       size = 10;
    else if((radius>120)&&(radius<500))
       size = 13+(radius-120)/30;
    else if(radius>=500)
       size = 13+(radius-120)/40;

    paint.setFont(QFont("Euphemia",size,QFont::DemiBold));

    QPoint TextPoint(0,radius*0.77-size*0.9);        //設置90°的文字
    TextPoint = CustomRotate(TextPoint,90,240);   //獲取點=210°的文字位置
    qreal TextRotate=210;

     for(int i=0;i<7;i++)              //設置7個刻度值
    {
    
          //... ...

          qreal Current_Value =(qreal)i*((maxvalue-minvalue)/6);

          if((Current_Value>value&&(paint.pen().color()!=ScaleColor)))
          {
              paint.setPen(ScaleColor);

          }
          else if((Current_Value<=value&&(paint.pen().color()!=slideScaleColor)))
          {
              paint.setPen(slideScaleColor);
          }

       paint.drawText(QRect(TextPoint.x()-size*1.5+offest[i].x(),TextPoint.y()-size*1.2+offest[i].y(),size*3,size*2.4),alingns[i],text.arg((maxvalue-minvalue)*i/6));
       TextPoint = CustomRotate(TextPoint,TextRotate,40);   //獲取點=210°的文字位置
       TextRotate-=40;
    }

    paint.restore();
}    

效果以下所示:

 6.而後接下來開始畫指針

void Dial::drawPointColor(QPainter &paint)          //繪製指針
{

    qreal PointTop;                //動態計算指針頭
    qreal PointBottom;             //動態計算指針底部
    if(radius<=120)
    {
        PointTop = 2;
        PointBottom = 6;
    }
    else if((radius>120)&&(radius<500))
    {
        PointTop = 2 + (radius-120)/100;
        PointBottom = PointTop*3;
    }
    else if(radius>=500)
    {
        PointTop = 2 + (radius-120)/140;
        PointBottom = PointTop*3;
    }

    //指針
    const QPointF  Pointer[4] = {
        QPointF(- PointTop / 2, radius*0.80),
        QPointF(PointTop / 2, radius*0.80),
        QPointF(PointBottom / 2, centerR*0.9),
        QPointF(-PointBottom / 2, centerR*0.9)
    };

    paint.save();


    paint.setBrush(PointerColor);
    paint.setPen(PointerColor.darker(300));


    qreal Current_Angle =60+(int)((value/(maxvalue-minvalue))*240);

    paint.rotate(Current_Angle);

    paint.drawConvexPolygon(Pointer, 4);

    paint.restore();

}

效果以下:

7.而後繼續畫中心圓

void Dial::drawCenterColor(QPainter &paint)      //繪製中心圓
{
    paint.save();

    QRadialGradient Radial(0,0,centerR,0,0);

    Radial.setColorAt(1,centercolor.lighter(170));
    Radial.setColorAt(0.98,centercolor.lighter(150));
    Radial.setColorAt(0.95,centercolor.lighter(130));
    Radial.setColorAt(0.70,centercolor);

    paint.setBrush(Radial);
    paint.drawEllipse(QPointF(0,0), centerR,centerR);

    paint.restore();

}

效果以下:

  

剩下的代碼就是畫標籤和值還有圖標啦,因爲漸變代碼多一些,因此具體參考能夠去下載源代碼.在最下面有下載地址

 


2018-06-30    第二次更新

內容

  • 支持負數到正數刻度值顯示
  • 支持小數點位數設置
  • 優化刻度值自適應窗口,能具體顯示個位至千位
  • 支持錶盤全部顏色搭配 
  • 添加arriveEnd()信號函數

並寫了個demo測試程序,能夠直接測試數據,demo程序效果圖以下所示:

該demo程序放在了提供的源碼地址裏了,下載好後,在文件夾demo2裏面

 

 測試圖1-設置顏色(任意搭配顏色):

 

測試圖2-設置正負數值:

 

 

 

 


2018-07-01    第三次更新

  •  在上個更新裏,添加了錶盤陰影效果,來實現立體感

以下圖的第二個錶盤所示:

 

該demo程序放在了提供的源碼地址裏了,下載好後,在文件夾demo3裏面

 

主要內容:

  添加了一個drawDialShade(QPainter &paint,qreal Angle_start,qreal Angle_end,qreal ratio,int alpha)成員函數,來繪製白色陰影,實現的光影效果.

該函數的參數含義以下所示:

  • Angle_start Angle_end :表示圓盤的起始/結束角度,Angle_end必須大於Angle_start哦
  • ratio:表示繪製的陰影亮度的扁與平(爲0~1之間),爲0表示平的圓環,爲0.99表示最扁的圓環,大於等於1則不會繪製
  • alpha:表示鋪上的白色透明度,0表示透明,255表示不透明

 

若是以爲上圖的陰影效果以爲不合適,能夠本身修改哦~

 

drawDialShade()函數使用示例:

1.單獨調用drawDialShade(painter,30,180,0,255)時

含義:  表示在內圓盤上的30°~180°之間繪製圓月,ratio=0,因此圓月是平的,alpha=255,表示不透明

效果以下:

2.單獨調用drawDialShade(painter,45,180,0.5,150)時

含義:  表示在內圓盤上的45°~180°之間繪製圓月,圓月是半扁的,半透明

效果以下:

 

PS:要實現更強的立體感,屢次調用改參數便可

 

 

上面全部源碼已放在源代碼下載地址裏了,具體源代碼下載地址爲: 

https://download.csdn.net/download/qq_37997682/10512710

 


2019-05-29 (QT5版本更新)

 

  • 因爲以前上傳的錶盤是QT4版本 編碼爲GBK的,對有些只學過QT5的同窗們很差移植,因此重新上傳一個QT5版本的,編碼格式爲utf-8

以下圖所示:

 下載地址爲:   https://download.csdn.net/download/qq_37997682/11214644

 

 

若是以爲不錯,點個讚唄~

相關文章
相關標籤/搜索