Если область отображения не была бы квадратом, таймер духовки принял бы форму эллипса, когда форма виджета перестанет быть квадратной после изменения его размеров. Чтобы избежать такой деформации, мы должны устанавливать область отображения и окно на прямоугольник с одинаковым соотношением сторон.
Теперь давайте рассмотрим программный код рисования:
01 void OvenTimer::draw(QPainter *painter)
02 {
03 static const int triangle[3][2] = {
04 { -2, -49 }, { +2, -49 }, { 0, -47 }
05 };
10 QPen thickPen(palette().foreground(), 1.5);
11 QPen thinPen(palette().foreground(), 0.5);
12 QColor niceBlue(150, 150, 200);
13 painter->setPen(thinPen);
14 painter->setBrush(palette().foreground());
15 painter->drawPolygon(QPolygon(3, ▵[0][0]));
Мы начинаем с отображения маленького треугольника в позиции 0 в верхней части виджета. Этот треугольник задается в программе тремя фиксированными координатами, и мы используем функцию
Одно из удобств применения механизма «окно—область отображения» заключается в том, что мы можем при программировании в командах рисования жестко задавать координаты точек и тем не менее добиваться необходимого изменения размеров.
16 QConicalGradient coneGradient(0, 0, -90.0);
17 coneGradient.setColorAt(0.0, Qt::darkGray);
18 coneGradient.setColorAt(0.2, niceBlue);
19 coneGradient.setColorAt(0.5, Qt::white);
20 coneGradient.setColorAt(1.0, Qt::darkGray);
21 painter->setBrush(coneGradient);
22 painter->drawEllipse(-46, -46, 92, 92);
Мы рисуем внешнюю окружность и заполняем ее, используя конический градиент. Центр градиента находится в точке (0, 0), а его угол равен —90°.
23 QRadialGradient haloGradient(0, 0, 20, 0, 0);
24 haloGradient.setColorAt(0.0, Qt::lightGray);
25 haloGradient.setColorAt(0.8, Qt::darkGray);
26 haloGradient.setColorAt(0.9, Qt::white);
27 haloGradient.setColorAt(1.0, Qt::black);
28 painter->setPen(Qt::NoPen);
29 painter->setBrush(haloGradient);
30 painter->drawEllipse(-20, -20, 40, 40);
Мы заполняем внутреннюю окружность, используя радиальный градиент. Центр и фокус градиента располагаются в точке (0, 0). Радиус градиента равен 20.
31 QLinearGradient knobGradient(-7, -25, 7, -25);
32 knobGradient.setColorAt(0.0, Qt::black);
33 knobGradient.setColorAt(0.2, niceBlue);
34 knobGradient.setColorAt(0.3, Qt::lightGray);
35 knobGradient.setColorAt(0.8, Qt::white);
36 knobGradient.setColorAt(1.0, Qt::black);
37 painter->rotate(duration() * DegreesPerSecond);
38 painter->setBrush(knobGradient);
39 painter->setPen(thinPen);
40 painter->drawRoundRect(-7, -25, 14, 50, 150, 50);
41 for (int i = 0; i <= MaxMinutes; ++i) {
42 if (i % 5 == 0) {
43 painter->setPen(thickPen);
44 painter->drawLine(0, -41, 0, -44);
45 painter->drawText(-15, -41, 30, 25,
46 Qt::AlignHCenter | Qt::AlignTop,
47 QString::number(i));
48 } else {