QT自定义仪表盘控件绘制,表盘指针缓冲运动

 QT自定义仪表盘控件绘制

 完整代码,

Dashboard1::Dashboard1(QWidget *parent) :
    QWidget(parent)//,
    //ui(new Ui::Dashboard1)
{
    setFixedSize(350,350);
    //setMaximumSize(100,100);
    //ui->setupUi(this);
    PaintTimer = new QTimer();
    MoveTimer = new QTimer();
    connect(PaintTimer,SIGNAL(timeout()),this,SLOT(update()));
    connect(MoveTimer,SIGNAL(timeout()),this,SLOT(timework()));
    PaintTimer->start(50);
   // setDashBoardEdgeColor
    qDialEdgeColor =  QColor(80,80,80);
}

Dashboard1::~Dashboard1()
{
    //delete ui;
}

void Dashboard1::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);//抗锯齿
    this->drawDashBoardWiget(&painter);



}

//指针缓冲运动
void Dashboard1::timework()
{
    if(qValue == moveToValue)
    {
        qDebug()<<qValue;
         MoveTimer->stop();
         qValue = moveToValue;
    }
    else
    {
        int dis = this->qValue - moveToValue;
        if(dis< 0)
        {   qValue+= (-dis)/2+1;
        }
        else if(dis> 0)
        {
            qValue-= (dis/2)+1;

        }

    }
}
void Dashboard1::qParmInit()
{
    qCircular = QPoint(width() / 2,height() / 2);//圆心位置刷新
    qRadius = (width() / 2);//外圆形的半径
    //qDialDivideSize = (qDialEdgeSize + qDialEdgeSize * 1.5);//刻度盘的大小
}


void Dashboard1::setOtherBackgroud(bool status,QPainter *painter)
{
    if(status == true)
    {
        painter->save();

        painter->setBrush(Qt::transparent);
        painter->fillRect(this->rect(), QColor(0, 0, 0, 0));
        painter->restore();
    }
}
//绘制控件
void Dashboard1::drawDashBoardWiget(QPainter *painter)
{
    //全局参数初始化
    qParmInit();
    setOtherBackgroud(true,painter);
    //绘制表盘
    drawDashBoard(painter);
    //绘制刻度尺
    drawDivideRule(painter);
    //绘制指针
    drawDishBoardPointer(painter);
    //绘制表盘文字
    drawDashBoardText(painter);
}

//绘制仪表盘
void Dashboard1::drawDashBoard(QPainter *painter)
{
    painter->save();

    painter->setBrush(Qt::transparent);
    painter->fillRect(this->rect(), QColor(0, 0, 0, 0));


    QBrush qBrush = QBrush(qDialEdgeColor);//灰色画刷,设置表盘边缘原色

    painter->setBrush(qBrush);//使用画刷

    painter->drawEllipse(qCircular,qRadius,qRadius);//绘制最外层圆盘

    qBrush.setColor(qDialDivideBackgroudColor);//黑色画刷

    painter->setBrush(qBrush);

    painter->drawEllipse(qCircular,qRadius - qDialEdgeSize,qRadius - qDialEdgeSize);//绘制黑色条带

    qBrush.setColor(qDialEdgeColor);//灰色画刷
    painter->setBrush(qBrush);
    painter->drawEllipse(qCircular,qRadius - qDialDivideSize,qRadius - qDialDivideSize);//绘制内层灰色圆盘

    qBrush =  QColor(162,88,88);//粉色画刷
    painter->setBrush(qBrush);
    painter->drawEllipse(qCircular,30,30);//内部最大粉色圆盘


    painter->restore();
}

void Dashboard1::drawDivideRule(QPainter *painter)
{
    painter->save();

    //下面开始绘制刻度,90度的间隔
    //x2 + y2 = r2
    //则圆上任一点为:(x1,y1)
    //x1   =   x0   +   r   *   cos(ao   *   3.14   /180   )
    //y1   =   y0   +   r   *   sin(ao   *   3.14   /180   )


    float fRadius = 0.0;
    //为了对称好看我们一般从逆时针90度位置开始绘制

    QPen qPen(Qt::white);
    qPen.setWidth(2);   //设置画笔的粗细
    painter->setPen(qPen);
    //先绘制左侧


#if 1
    for(int uiLoop = 0;uiLoop < (fMaxDivide * fMinDivide) + 1 ;uiLoop++)
    {
        float fAngle = (BaseAngle + ((float)270 / (fMaxDivide * fMinDivide)) * uiLoop);

        fRadius = (qRadius - 21);

        int x1Start = qCircular.x() + fRadius * cos(fAngle * 3.14 / 180);
        int y1Start = qCircular.y() + fRadius * sin(fAngle * 3.14 / 180);

        if(uiLoop % fMinDivide == 0)
        {

            fRadius = qRadius - qDialDivideSize + 1;
        }
        else
        {
            fRadius = qRadius - (qDialDivideSize / 1.3);
        }
        int x2End = qCircular.x() + fRadius * cos(fAngle * 3.14 / 180);
        int y2End =  qCircular.y() + fRadius * sin(fAngle * 3.14 / 180);

        painter->drawLine(QPoint(x1Start,y1Start),QPoint(x2End,y2End));
    }
#endif
    painter->restore();
}

void Dashboard1::drawDashBoardText(QPainter *painter)
{
    painter->save();

    QPen qPen(Qt::white);
    qPen.setWidth(2);   //设置画笔的粗细
    painter->setPen(qPen);

    //绘制表盘文字
    QFont qFont("楷体",28,QFont::Bold,false);
    painter->setFont(qFont);//
    painter->drawText(QRectF(qCircular.x() - 17,qCircular.y() + 85,80,80),QString::number(qValue));
    float fRadius = 0.0;
    //通过公式计算刻度文字的位置信息。
    for(int uiLoop = 0;uiLoop < (fMaxDivide ) + 1 ;uiLoop++)
    {
        int PointeNum = ((fMaxValue / fMaxDivide) * uiLoop);

        float fAngle = (BaseAngle + ((float)270 / (fMaxDivide)) * uiLoop);


        fRadius = (qRadius - 75) ;//- 18
        fAngle += 4;


        int x1Start = qCircular.x() + fRadius * cos(fAngle * 3.14 / 180);
        int y1Start = qCircular.y() + fRadius * sin(fAngle * 3.14 / 180);

        QFont qFonts("楷体",12,QFont::Bold,false);
      // QRect rc =qFonts.boundingRect(QString::number((fMaxValue / fMaxDivide) * uiLoop));
      // rc.center();
        int textWidth = fontMetrics().width(QString::number(PointeNum));
        int textHeight = fontMetrics().height();//QString::number(PointeNum)

        painter->setFont(qFonts);
//QRectF(x1Start-textWidth/2,y1Start-(textHeight+1)/2,80,80)
        painter->drawText(x1Start-textWidth/2-3,y1Start+(textHeight+1)/4+1,QString::number((fMaxValue / fMaxDivide) * uiLoop));//QString::number((fMaxValue / fMaxDivide) * uiLoop)
    }

    painter->restore();
}
//绘制指针
void Dashboard1::drawDishBoardPointer(QPainter *painter)
{
    painter->save();

    QBrush qBrush = QBrush(QColor(Qt::red));

    painter->setBrush(qBrush);


    QPen qPen(Qt::red);
    qPen.setWidth(2);   //设置画笔的粗细
    painter->setPen(qPen);

    float fRadius = 0.0;
    if(qValue > fMaxValue)
    {
        qValue = fMaxValue;
    }

    float fAngle = (BaseAngle + ((float)270 / (fMaxValue)) * qValue);//指针中心角度信息。
    float fRightAngle = fAngle + 90;//右侧角度
    float fLeftAngle = fAngle - 90;//左侧角度

    fRadius = (qRadius - 21);

    int x1Start = qCircular.x() + (qRadius - qDialDivideSize - 3) * cos(fAngle * 3.14 / 180);
    int y1Start = qCircular.y() + (qRadius - qDialDivideSize - 3) * sin(fAngle * 3.14 / 180);


    fRadius = qRadius - (qDialDivideSize / 1.3);

    int x2End = qCircular.x(); //+ fRadius * cos(fAngle * 3.14 / 180);
    int y2End =  qCircular.y(); //+ fRadius * sin(fAngle * 3.14 / 180);

    int x3End = qCircular.x() + 10 * cos(fRightAngle * 3.14 / 180);//过圆心的右侧切点
    int y3End = qCircular.y() + 10 * sin(fRightAngle * 3.14 / 180);

    int x4End = qCircular.x() + 10 * cos(fLeftAngle * 3.14 / 180);//过圆心的左侧切点
    int y4End = qCircular.y() + 10 * sin(fLeftAngle * 3.14 / 180);


    QPointF qTriangle[3] = {QPoint(x1Start,y1Start),QPoint(x3End,y3End),QPoint(x4End,y4End)};

    painter->drawPolygon(qTriangle,3);
    painter->drawEllipse(qCircular,15,15);//内部小粉色圆盘
    painter->restore();
}

void Dashboard1::setValue(int qValue)
{
    this->qValue = qValue;
}
//动态移动到对应值
void Dashboard1::MovetoValue(int qValue1)
{
    MoveTimer->start(50);
    moveToValue = qValue1;

}


void Dashboard1::setMaxValue(float fMaxValue)
{
    this->fMaxValue = fMaxValue;
}

void Dashboard1::setDashBoardEdgeColor(QColor &qColor)
{
    qDialEdgeColor = qColor;
}

void Dashboard1::setDashDivideBackgroudColor(QColor &qColor)
{
    qDialDivideBackgroudColor = qColor;
}

主窗口中调用

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m  = new QWidget(this);
    QVBoxLayout * layout = new QVBoxLayout(ui->centralWidget);//铺满布局
    dashboard1 = new Dashboard1(this);

    ui->centralWidget->setFixedWidth(404);
    layout->addWidget(dashboard1);
    layout->addWidget(ui->horizontalSlider);

    dashboard1->adjustSize();
    ui->horizontalSlider->setFixedWidth(350);
    dashboard1->setMaxValue(100);
    setFixedWidth(410);



}

指针的简单缓冲运动效果 如下:调用MovetoValue()函数

 

参考代码来自https://www.bilibili.com/video/av56523957?from=search&seid=16196098167729854781,在该基础上做了更改

修改后Demo完整源码下载地址:

 

https://download.csdn.net/download/gws09876/11986629

 

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gws09876

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值