Qt浅谈之四十二钟表摆动显示百分比

一、简介

        Qt下利用定时器实现指针指示百分比的钟摆的动态显示效果,可以适用于显示百分比或进度条的进度或时间的刻度值(在圆形进度条上的一种改进)。效果如下:
Qt浅谈之四十二钟表摆动显示百分比_第1张图片

二、详解

1、代码

(1)DashboardDisplay.h
#ifndef DASHBOARDPROCESS_H
#define DASHBOARDPROCESS_H

#include <QtCore>
#include <QtGui>

class DashboardProcess : public QWidget
{
    Q_OBJECT

public:
    DashboardProcess(QWidget *parent = 0);
    ~DashboardProcess();
    void setUsedValue(int value);
    void setSize(int width, int height);

protected:
    void paintEvent(QPaintEvent *event);
    void resizeEvent (QResizeEvent * event);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void showEvent(QShowEvent *event);
    void hideEvent(QHideEvent *event);

private slots:
    void slotUpdateTimer();
    void slotGapTimer();

private:
    QPoint beginDrag;
    bool bPressFlag;
    int typeDisplay;

    QPixmap pointPix;
    int userdVaule;
    int currentValue;
    QLabel *currentValueLabel;

    QTimer *updateTimer;
    QTimer *gapTimer;
    int gap;
    int gapCount;
};

#endif // WIDGET_H
(2)DashboardDisplay.cpp
#include "DashboardDisplay.h"
#define LOOPCOUNT 8
DashboardProcess::DashboardProcess(QWidget *parent)
    : QWidget(parent, Qt::FramelessWindowHint)
    ,bPressFlag(false)
    , currentValue(0)
    , gap(0)
    , gapCount(LOOPCOUNT)
{
    QTextCodec *codec = QTextCodec::codecForName("utf8");
    QTextCodec::setCodecForLocale(codec);
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);
    resize(159, 159);
    setAutoFillBackground(false);
    QPalette pal = palette();
    pal.setColor(QPalette::Background, QColor(0xFF,0xFF,0xFF,0xFF));
    setPalette(pal);
    pointPix.load(":/dashboard_pointer_bg.png");

    currentValueLabel = new QLabel(tr("0%"), this);
    currentValueLabel->setFont(QFont("Arial", 10, QFont::Normal));
    currentValueLabel->setAlignment(Qt::AlignCenter);
    currentValueLabel->setStyleSheet("color:#19649f");

    updateTimer = new QTimer(this);
    updateTimer->setInterval(8);
    connect(updateTimer, SIGNAL(timeout()), this, SLOT(slotUpdateTimer()));

    gapTimer = new QTimer(this);
    gapTimer->setInterval(10);
    connect(gapTimer, SIGNAL(timeout()), this, SLOT(slotGapTimer()));
}

DashboardProcess::~DashboardProcess()
{
    if (updateTimer->isActive()) {
        updateTimer->stop();
    }
    if (gapTimer->isActive()) {
        gapTimer->stop();
    }
}

void DashboardProcess::setUsedValue(int value)
{
    userdVaule = value;
}

void DashboardProcess::showEvent(QShowEvent *event)
{
    if (userdVaule > 0) {
        updateTimer->start();
    }
    gap = 0;
    gapCount = LOOPCOUNT;
    currentValue = 0;
}

void DashboardProcess::hideEvent(QHideEvent *event)
{
    if (updateTimer->isActive()) {
        updateTimer->stop();
    }
    if (gapTimer->isActive()) {
        gapTimer->stop();
    }
    currentValue = 0;
    gap = 0;
    gapCount = LOOPCOUNT;
}

void DashboardProcess::slotUpdateTimer()
{
    if (currentValue >= userdVaule) {
        currentValue = userdVaule;
        updateTimer->stop();
        --gapCount;
        gap = gapCount*4;
        gapTimer->start();
    }
    else {
        ++currentValue;
    }
    if (currentValue >= 0) {
        currentValueLabel->setText(QString("%1%").arg(currentValue));
    }
    update();
}

void DashboardProcess::slotGapTimer()
{
    if (gap < 0) {
        gapTimer->stop();
        --gapCount;
        if (gapCount > 0) {
            gapTimer->start();
            gap = gapCount * 4;
        }
        return;
    }
    --gap;
    update();
}

void DashboardProcess::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    QColor usedColor(165, 220, 62);
    QColor freeColor(215, 215, 215);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::SmoothPixmapTransform);

    painter.save();
    painter.translate(width() / 2, height() / 2);
    painter.rotate(42);
    painter.setPen(QPen(usedColor, 2));
    for (int i = 0; i < currentValue ; ++i) {
        painter.drawLine(0, 60, 0, 70);
        painter.rotate(2.8);
    }
    painter.setPen(QPen(freeColor, 2));
    for (int i = currentValue; i < 100 ; ++i) {
        painter.drawLine(0, 60, 0, 70);
        painter.rotate(2.8);
    }
    painter.restore();

    painter.save();
    painter.translate(width() / 2, height() / 2);
    painter.rotate(-2);
    if (gapCount < LOOPCOUNT && gapCount >= 0) {
        if (gap >= gapCount * 3) {
            painter.rotate((qreal)(360 - 42 * 2)/100 * currentValue - 2 + gapCount * 4 - gap);
        }
        else if (gap >= gapCount * 2) {
            painter.rotate((qreal)(360 - 42 * 2)/100 * currentValue - 2 + gap - gapCount *2);
        }
        else if (gap >= gapCount) {
            painter.rotate((qreal)(360 - 42 * 2)/100 * currentValue - 2 - (gapCount *2 - gap));
        }
        else {
            painter.rotate((qreal)(360 - 42 * 2)/100 * currentValue - 2 - gap);
        }
    }
    else {
        if (currentValue >= 0) {
            painter.rotate((qreal)(360 - 42 * 2)/100 * currentValue - 2);
        }
    }
    painter.drawPixmap(QRect((- pointPix.width())/2 , (- pointPix.height())/2, pointPix.width(), pointPix.height()) , pointPix);
    painter.restore();
}

void DashboardProcess::resizeEvent(QResizeEvent *event)
{
    currentValueLabel->setGeometry(0, 122, width(), 20);
    move((QApplication::desktop()->width() - width())/2,  (QApplication::desktop()->height() - height())/2);
    QWidget::resizeEvent(event);
}

/****************move everywhere*******************/
void DashboardProcess::mousePressEvent(QMouseEvent *event)
{
    bPressFlag = true;
    beginDrag = event->pos();
    QWidget::mousePressEvent(event);
}

void DashboardProcess::mouseMoveEvent(QMouseEvent *event)
{
    if (bPressFlag) {
        QPoint relaPos(QCursor::pos() - beginDrag);
        move(relaPos);
    }
    QWidget::mouseMoveEvent(event);
}

void DashboardProcess::mouseReleaseEvent(QMouseEvent *event)
{
    bPressFlag = false;
    QWidget::mouseReleaseEvent(event);
}
(3)main.cpp
#include "DashboardDisplay.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    DashboardProcess w;
    w.setUsedValue(70);
    w.show();

    return a.exec();
}

2、编译运行

Qt浅谈之四十二钟表摆动显示百分比_第2张图片
指针摆动的最大摆角为LOOPCOUNT变量,一个周期内钟摆的振幅改变两次(4个来回) ,每一个周期摆角减少1度,直到最终为0。

三、总结

(1)上述的数据在实际应用中还得微调,根据背景图片的不同rotate的角度不同,定时器的时间根据自己的需求加以调整。
(2)若有问题或建议,请留言,在此感谢!

你可能感兴趣的:(linux,qt)