Для иллюстрации преобразования рисовальщика мы рассмотрим программный код виджета OvenTimer (таймер духовки), показанного на рис. 8.9. Виджет OvenTimer имитирует кухонные таймеры, которые широко использовались до того, как в духовках стали применяться встроенные часы. Пользователь может повернуть ручку и установить требуемую длительность. Диск переключателя автоматически поворачивается против часовой стрелки, пока не достигнет отметки 0, в результате чего OvenTimer генерирует сигнал timeout.
01 class OvenTimer : public QWidget
02 {
03 Q_OBJECT
04 public:
05 OvenTimer(QWidget *parent = 0);
06 void setDuration(int secs);
07 int duration const;
08 void draw(QPainter *painter);
09 signals:
10 void timeout;
11 protected:
12 void paintEvent(QPaintEvent *event);
13 void mousePressEvent(QMouseEvent *event);
14 private:
15 QDateTime finishTime;
16 QTimer *updateTimer;
17 QTimer *finishTimer;
18 }
Класс OvenTimer наследует QWidget и
переопределяет две виртуальные функции: paintEvent и mousePressEvent.
Мы начнем с нескольких констант, управляющих внешним видом и режимом работы таймера духовки.
01 OvenTimer::OvenTimer(QWidget *parent)
02 : QWidget(parent)
03 {
04 finishTime = QDateTime::currentDateTime;
05 updateTimer = new QTimer(this);
06 connect(updateTimer, SIGNAL(timeouf),
07 this, SLOT(update));
08 finishTimer = new QTimer(this);
09 finishTimer->setSingleShot(true);
10 connect(finishTimer, SIGNAL(timeout),
11 this, SIGNAL(timeout));
12 connect(finishTimer, SIGNAL(timeout),
13 updateTimer, SLOT(stop));
14 }
В конструкторе мы создаем два объекта QTimer: updateTimer используется для обновления внешнего вида виджета через каждую секунду, a finishTimer генерирует сигнал виджета timeout
при достижении отметки 0. Объект finishTimer должен генерировать только один сигнал тайм-аута, поэтому мы вызываем setSingleShot(true); по умолчанию таймеры запускаются повторно, пока они не будут остановлены или не будут уничтожены. Последний вызов connect является оптимизационным и обеспечивает прекращение обновления виджета каждую секунду, когда таймер неактивен.
Функция setDuration выставляет таймер духовки, задавая требуемое количество секунд. Время окончания мы рассчитываем путем добавления продолжительности его работы к текущему времени, полученному функцией QDateTime::currentDateTime, и сохраняем его в закрытой переменной finishTime. B конце мы вызываем update для перерисовки виджета с новой продолжительностью работы.
Переменная finishTime имеет тип QDateTime. Поскольку она содержит дату и время, мы избегаем ошибки из-за смены суток, когда текущее время оказывается до полуночи, а время окончания — после полуночи.
01 int OvenTimer::duration const
02 {
03 int secs = QDateTime::currentDateTime.
04 secsTo(finishTime);
05 if (secs < 0)
06 secs = 0;
07 return secs;
08 }
Функция duration возвращает количество секунд, оставшееся до завершения работы таймера. Если таймер неактивен, мы возвращаем 0.