C++ (Qt)#ifndef SHEDULEINDICATOR_H#define SHEDULEINDICATOR_H #include <QtCore/QMap> #include <QtGui/QWidget> class SheduleIndicator : public QWidget{ Q_OBJECT public: explicit SheduleIndicator (QWidget *parent = 0); void setShedule (const QMap <int, bool> &shedule) { shedule_ = shedule; drawImage(); } protected: virtual void showEvent (QShowEvent *); virtual void paintEvent (QPaintEvent *event); private: void drawImage (); private: QMap <int, bool> shedule_; QPixmap image_;}; #endif //SHEDULEINDICATOR_H
C++ (Qt)#include <QtCore/QTimer>#include <QtCore/QTime> #include <QtGui/QPainter>#include <QRadialGradient>#include <QLinearGradient>#include <QConicalGradient> #include "sheduleindicator.h" enum {UpdateInterval = 1000 * 60 * 1}; SheduleIndicator::SheduleIndicator (QWidget *parent) : QWidget (parent){ QTimer *timer = new QTimer (this); connect (timer, SIGNAL (timeout()), SLOT (update())); timer->start (UpdateInterval);} void SheduleIndicator::drawImage (){ image_ = QPixmap (size ()); image_.fill (Qt::transparent); const int side = qMin (width(), height()); QPainter painter; painter.begin (&image_); painter.setRenderHint (QPainter::Antialiasing); painter.translate (width() / 2, height() / 2); painter.scale (side / 200.0, side / 200.0); const int radius = 65; const int width = 30; const QRect rectangle (-radius, -radius, radius * 2, radius * 2); static const QColor insideColor (Qt::darkGray); static const QColor offColor (QColor (195, 195, 195)); static const QColor onColor (QColor (228, 131, 16)); static const QColor foreGroundColor (QColor (95, 95, 105)); static const QColor digitsColor (QColor (195, 195, 195)); static const QColor edgeColor (QColor (26, 26, 26)); painter.setPen (QPen (edgeColor, 1)); painter.setBrush (Qt::NoBrush); painter.drawEllipse (QPoint (0, 0), radius + width / 2, radius + width / 2); painter.drawEllipse (QPoint (0, 0), radius - width / 2, radius - width / 2); QPen sectionPen; sectionPen.setWidth (width); sectionPen.setCapStyle (Qt::FlatCap); for (int i = 0; i < 24; ++i) { QRadialGradient circle (0, 0, radius + width / 2, 0, 0); circle.setColorAt (0.0, insideColor); circle.setColorAt (0.62, insideColor); circle.setColorAt (0.63, foreGroundColor); circle.setColorAt (shedule_ [i] ? 0.68 : 0.65, shedule_ [i] ? onColor : offColor); circle.setColorAt (shedule_ [i] ? 0.95 : 0.98, shedule_ [i] ? onColor : offColor); circle.setColorAt (1.0, foreGroundColor); sectionPen.setBrush (circle); painter.setPen (sectionPen); painter.drawArc (rectangle, 75 * 16, 15 * 16); painter.rotate (15); } painter.setPen (QPen (foreGroundColor, 1)); for (int i = 0; i < 24; i++) { painter.drawLine (0, radius - width / 2, 0, radius + width / 2); painter.rotate (15); } painter.setBrush (insideColor); painter.setPen (insideColor); painter.drawEllipse (QPoint (0, 0), radius - width / 2 - 1, radius - width / 2 - 1); // Digits const QRectF rectangle1 (-100.0, -100.0, 200.0, 200.0); painter.setPen (digitsColor); painter.drawText (rectangle1, Qt::AlignTop | Qt::AlignHCenter, "0"); painter.drawText (rectangle1, Qt::AlignBottom | Qt::AlignHCenter, "12"); painter.drawText (rectangle1, Qt::AlignLeft | Qt::AlignVCenter, "18"); painter.drawText (rectangle1, Qt::AlignRight | Qt::AlignVCenter, "6 "); painter.end();} void SheduleIndicator::showEvent (QShowEvent *e){ QWidget::showEvent (e); drawImage();} void SheduleIndicator::paintEvent (QPaintEvent *){ const int side = qMin (width(), height()); QPainter painter (this); painter.drawPixmap (QPoint (0, 0), image_); painter.setRenderHint (QPainter::Antialiasing); painter.translate (width() / 2, height() / 2); painter.scale (side / 200.0, side / 200.0); static const QPointF p0 (0, 10); static const QPointF p1 (5, 5); static const QPointF p2 (0.5, -70); static const QPointF p3 (-0.5, -70); static const QPointF p4 (-5, 5); static const QPointF hourHand [5] = {p0, p1, p2, p3, p4}; painter.setPen (Qt::NoPen); // Hand painter.save(); const QTime time = QTime::currentTime(); painter.translate (QPoint (-2, 2));; painter.rotate (15.0 * (time.hour() + time.minute() / 60.0)); painter.setBrush (QColor (0x40, 0x40, 0x40, 100)); painter.drawConvexPolygon (hourHand, 5); painter.rotate (-15.0 * (time.hour() + time.minute() / 60.0)); painter.translate (QPoint (2, -2));; painter.rotate (15.0 * (time.hour() + time.minute() / 60.0)); QLinearGradient handGradient (p1, p4); handGradient.setColorAt (0.0, Qt::blue); handGradient.setColorAt (0.5, Qt::darkBlue); handGradient.setColorAt (1.0, Qt::blue); painter.setBrush (handGradient); painter.drawConvexPolygon (hourHand, 5); painter.restore(); // hand pin QRadialGradient handCircle (0, 0, 4, 0, 0); handCircle.setColorAt (0.0, Qt::white); handCircle.setColorAt (1.0, Qt::darkBlue); painter.setBrush (handCircle); painter.drawEllipse (QPoint (0, 0), 4, 4);}
C++ (Qt)int GetSector( const QPoint & locMouse, const QPoint & center, int num = 12 ){ QPoint delta = locMouse - center; qreal angle = atan2(-delta.y(), delta.x()); // в экранных координатах y идет вниз, поэтому y с минусом static const qreal PI2 = 3.141592 * 2; if (angle < 0) angle += PI2; return (int) (angle / PI2 * num);}
C++ (Qt)sector = ((12 - sector) + 3) % 12;
C++ (Qt)void SheduleIndicator::mousePressEvent (QMouseEvent *e){ if (mode_ != Edit) { return; } const QPoint center (width () / 2, height () / 2); const QPoint point (e->pos ().x ()- center.x (), center.y () - e->pos ().y ()); const int distance = qSqrt (qPow ((center.x () - e->pos ().x ()), 2) + qPow ((center.y () - e->pos ().y ()), 2)); if (distance >= RMin && distance <= RMax) { qreal angle = qAcos (point.y () / qSqrt (qPow (point.x (), 2) + qPow (point.y (), 2))); if (point.x () < 0) { angle = 2 * M_PI - angle; } const int i = angle / (2 * M_PI / 24); shedule_ [i] = !shedule_ [i]; emit sheduleChanged (); drawImage (); repaint (); }}