一、运行效果
在这里插入图片描述
二、完整源码
#ifndef OVENTIMER_H #define OVENTIMER_H
#include <QWidget> #include <QDateTime>
class QTimer;
#ifdef quc class Q_DECL_EXPORT OvenTimer : public QWidget #else class OvenTimer : public QWidget #endif
{ Q_OBJECT public: explicit OvenTimer(QWidget *parent = 0); ~OvenTimer();
protected: void mousePressEvent(QMouseEvent *event); void paintEvent(QPaintEvent *); void draw(QPainter *painter);
private: int duration; QDateTime finishTime;
QTimer *updateTimer; QTimer *finishTimer;
public: int getDuration() const; QSize sizeHint() const; QSize minimumSizeHint() const;
public Q_SLOTS: void setDuration(int secs);
Q_SIGNALS: void timeout(); };
#endif
#pragma execution_character_set("utf-8")
#include "oventimer.h" #include "qpainter.h" #include "qevent.h" #include "qtimer.h" #include "qdatetime.h" #include "qmath.h" #include "qpixmap.h" #include "qdebug.h"
const double DegreesPerMinute = 7.0; const double DegreesPerSecond = DegreesPerMinute / 60; const int MaxMinutes = 45; const int MaxSeconds = MaxMinutes * 60; const int UpdateInterval = 1;
OvenTimer::OvenTimer(QWidget *parent) : QWidget(parent) { finishTime = QDateTime::currentDateTime();
updateTimer = new QTimer(this); connect(updateTimer, SIGNAL(timeout()), this, SLOT(update()));
finishTimer = new QTimer(this); finishTimer->setSingleShot(true); connect(finishTimer, SIGNAL(timeout()), this, SIGNAL(timeout())); connect(finishTimer, SIGNAL(timeout()), updateTimer, SLOT(stop()));
setFont(QFont("Arial", 8)); }
OvenTimer::~OvenTimer() { if (updateTimer->isActive()) { updateTimer->stop(); }
if (finishTimer->isActive()) { finishTimer->stop(); } }
void OvenTimer::mousePressEvent(QMouseEvent *event) { QPointF point = event->pos() - rect().center(); double theta = qAtan2(-point.x(), point.y()) * 180.0 / M_PI; setDuration(getDuration() + int(theta / DegreesPerSecond)); }
void OvenTimer::paintEvent(QPaintEvent *) { int width = this->width(); int height = this->height(); int side = qMin(width, height);
QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true);
painter.setViewport((width - side) / 2, (height - side) / 2, side, side); painter.setWindow(-50, -50, 100, 100); draw(&painter); }
void OvenTimer::draw(QPainter *painter) { static const int triangle[3][2] = { {-2, -49}, {+2, -49}, {0, -47} };
QPen thickPen(palette().windowText(), 1.5); QPen thinPen(palette().windowText(), 0.5);
painter->setPen(thinPen); painter->setBrush(palette().windowText()); painter->drawPolygon(QPolygon(3, &triangle[0][0]));
QConicalGradient coneGradient(0, 0, -90.0); coneGradient.setColorAt(0.0, Qt::darkGray); coneGradient.setColorAt(0.5, Qt::white); coneGradient.setColorAt(1.0, Qt::darkGray);
painter->setBrush(coneGradient); painter->drawEllipse(-46, -46, 92, 92);
QRadialGradient haloGradient(0, 0, 20, 0, 0); haloGradient.setColorAt(0.0, Qt::lightGray); haloGradient.setColorAt(0.8, Qt::darkGray); haloGradient.setColorAt(0.9, Qt::white); haloGradient.setColorAt(1.0, Qt::black);
painter->setPen(Qt::NoPen); painter->setBrush(haloGradient); painter->drawEllipse(-20, -20, 40, 40);
QLinearGradient knobGradient(-7, -25, 7, -25); knobGradient.setColorAt(0.0, Qt::black); knobGradient.setColorAt(0.3, Qt::lightGray); knobGradient.setColorAt(0.8, Qt::white); knobGradient.setColorAt(1.0, Qt::black);
painter->setPen(Qt::NoPen); painter->setBrush(knobGradient); painter->rotate(getDuration()*DegreesPerSecond); painter->drawRoundedRect(-7, -25, 14, 50, 10, 10);
for (int i = 0; i <= MaxMinutes; ++i) { painter->save(); painter->rotate(-i * DegreesPerMinute);
if (i % 5 == 0) { painter->setPen(thickPen); painter->drawLine(0, -41, 0, -44); painter->drawText(-15, -41, 30, 30, Qt::AlignHCenter | Qt::AlignTop, QString::number(i)); } else { painter->setPen(thinPen); painter->drawLine(0, -42, 0, -44); }
painter->restore(); } }
int OvenTimer::getDuration() const { int secs = QDateTime::currentDateTime().secsTo(finishTime); if (secs < 0) { secs = 0; } return secs; }
QSize OvenTimer::sizeHint() const { return QSize(200, 200); }
QSize OvenTimer::minimumSizeHint() const { return QSize(50, 50); }
void OvenTimer::setDuration(int secs) { secs = qBound(0, secs, MaxSeconds);
finishTime = QDateTime::currentDateTime().addSecs(secs); if (secs > 0) { updateTimer->start(UpdateInterval * 1000); finishTimer->start(secs * 1000); } else { updateTimer->stop(); finishTimer->stop(); }
this->update(); }
三、其他
-
国内开源:https://gitee.com/feiyangqingyun
-
国际开源:https://github.com/feiyangqingyun
-
项目大全:https://qtchina.blog.csdn.net/article/details/97565652
-
联系方式:微信 feiyangqingyun
-
官方店:https://shop114595942.taobao.com/