Qt 实现刻度盘

450 阅读1分钟

Qt实现刻度盘

kaikaicoming

kaikaicoming

麻瓜编程爱好者

效果图:

刻度盘.gif 项目源码

www.aliyundrive.com/s/ATH4Tz1Lh…

\

制作这个表盘最好继承自QWidget,这样可以放更方便的把它嵌入到自己的程序中

在类中声明如下成员:

protected:
    void paintEvent(QPaintEvent *) override;
    void timerEvent(QTimerEvent *) override;
    void resizeEvent(QResizeEvent *) override;

private:
    //经过计算后的刻度
    float step;
    //图表的中心
    QPointF midpoint;
    //当前数值
    float nowValue;

    int timer1s;

    //表盘各个模块
    void paintnFrame(QPainter &);
    void paintPointer(QPainter &);
    void paintScale(QPainter &);
    void paintDisplayValue(QPainter &);
public:
    //外部设置数值
    float setValue;
    //设置窗口大小
    int windowsSize;

初始化:

    setValue = nowValue = 100;
    step = 2.7;
    resize(windowsSize, windowsSize);
// 如果需要实时调整大小,可以将这两句放到 resizeEvent(QResizeEvent *) 中
    windowsSize=400;
    midpoint = QPointF(windowsSize/2, windowsSize/2);

// 可有可无的
    QDial *dial = new QDial(this);
    dial->move(0,0);
    dial->resize(50,50);
    dial->setMaximum(100);
    dial->show();
    connect(dial,&QDial::valueChanged,this,&pdial::dialtoNowvalue);
    //这个是因为还没有想到其他实现指针跟步移动的好办法
    timer1s = startTimer(10);

画出渐变底色

void pdial::paintnFrame(QPainter &painter)
{
    QConicalGradient grad(0, 0, -90);
    grad.setColorAt(0.1, Qt::red);
    grad.setColorAt(0.5, Qt::blue);
    grad.setColorAt(0.9, Qt::green);
    painter.setBrush(grad);
    painter.setPen(Qt::NoPen);
    painter.drawPie(QRect(-midpoint.x(), -midpoint.y(), windowsSize, windowsSize),-135 * 16,-step * nowValue * 16);
    painter.setBrush(Qt::white);
    painter.drawEllipse(QPointF(0,0), midpoint.x() * (135 / 150.0), midpoint.y() * (135 / 150.0));
}

画出刻度

void pdial::paintScale(QPainter &painter)
{
    painter.setPen(Qt::black);
    for(int i = 0;i <= 10;i++){
        int nowScale = i * 10;
        float arc = (nowScale * step + 135) / 180 * 3.1415926;
        QPointF text(midpoint.x() * (110 / 150.0) * cos(arc)-midpoint.x() / 15.0,
                     midpoint.y() * (110 / 150.0) * sin(arc)+midpoint.x() / 20.0);
        painter.drawText(text, QString::number(nowScale));
    }


    painter.save();
    painter.rotate(-45);
    for(int i = 0;i <= 100;i++){
        if(i % 10 == 0)
            painter.drawLine(-midpoint.x(), 0, -1 * (midpoint.x() * (130 / 150.0)), 0);
        else
            painter.drawLine(-midpoint.x(), 0, -1 * (midpoint.x() * (145 / 150.0)), 0);
        painter.rotate(step);
    }

    painter.restore();
}

画出指针

void pdial::paintPointer(QPainter &painter)
{
    painter.save();
    painter.rotate(-45+nowValue*step);
    painter.setPen(Qt::NoPen);
    QPointF triangle[] = {
        QPointF(-midpoint.x(), 0),
        QPointF(0, midpoint.x() * (10 / 150.0)),
        QPointF(0, -midpoint.x() * (10 / 150.0))
    };
    painter.setBrush(Qt::red);
    painter.drawPolygon(triangle,3);
    float globule = -midpoint.x() * (17 / 150.0);
    painter.drawEllipse(QPointF(0,0),globule,globule);
    painter.setBrush(Qt::white);
    painter.drawEllipse(QPointF(0,0),globule*0.4,globule*0.4);


    painter.restore();
}

显示当前值

void pdial::paintDisplayValue(QPainter &painter)

{

    painter.setPen(QPen(Qt::black,3));

    float wid = windowsSize*(60/300.0);

    QRectF rect(-wid/2,-wid/4+wid*1.2,wid,wid/2);

    painter.drawRoundedRect(rect,wid/5,wid/5);

    painter.drawText(rect,Qt::AlignCenter,QString::number(setValue));

}

最后在paintevent()中放出来就行了

void pdial::paintEvent(QPaintEvent *)

{

    QPainter painter(this);

    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::white);
    painter.drawRect(0,0,width(), height());

    painter.setRenderHint(QPainter::Antialiasing);
    painter.translate(midpoint);
    painter.setFont(QFont("arial", windowsSize / 25));


    paintnFrame(painter);
    paintPointer(painter);
    paintScale(painter);
    paintDisplayValue(painter);

}

附录

\

指针根步移动, 非常欢迎各位提供更好的办法。

void pdial::timerEvent(QTimerEvent *ev)

{

    if(ev->timerId() == timer1s){

        if(nowValue < setValue){

            nowValue += 1;

            update();

        }else if(nowValue > setValue){

            nowValue -= 1;

            update();

        }
    }
}

这是窗口大小变动事件

void pdial::resizeEvent(QResizeEvent *)
{
    windowsSize = width();
    midpoint = QPointF(windowsSize / 2, windowsSize / 2);
}

\

编程经验比较拉跨各位见谅>_<。

这边没有放出所有代码,可以下载源码看看 想知道如何改刻度范围的可以k我