1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example widgets/analogclock
\title Analog Clock Example
\brief The Analog Clock example shows how to draw the contents of a custom
widget.
\image analogclock-example.png Screenshot of the Analog Clock example
This example also demonstrates how the transformation and scaling
features of QPainter can be used to make drawing custom widgets
easier.
\section1 AnalogClock Class Definition
The \c AnalogClock class provides a clock widget with hour and minute
hands that is automatically updated every few seconds.
We subclass \l QWidget and reimplement the standard
\l{QWidget::paintEvent()}{paintEvent()} function to draw the clock face:
\snippet examples/widgets/analogclock/analogclock.h 0
\section1 AnalogClock Class Implementation
\snippet examples/widgets/analogclock/analogclock.cpp 1
When the widget is constructed, we set up a one-second timer to
keep track of the current time, and we connect it to the standard
\l{QWidget::update()}{update()} slot so that the clock face is
updated when the timer emits the \l{QTimer::timeout()}{timeout()}
signal.
Finally, we resize the widget so that it is displayed at a
reasonable size.
\snippet examples/widgets/analogclock/analogclock.cpp 8
\snippet examples/widgets/analogclock/analogclock.cpp 10
The \c paintEvent() function is called whenever the widget's
contents need to be updated. This happens when the widget is
first shown, and when it is covered then exposed, but it is also
executed when the widget's \l{QWidget::update()}{update()} slot
is called. Since we connected the timer's
\l{QTimer::timeout()}{timeout()} signal to this slot, it will be
called at least once every five seconds.
Before we set up the painter and draw the clock, we first define
two lists of \l {QPoint}s and two \l{QColor}s that will be used
for the hour and minute hands. The minute hand's color has an
alpha component of 191, meaning that it's 75% opaque.
We also determine the length of the widget's shortest side so that we
can fit the clock face inside the widget. It is also useful to determine
the current time before we start drawing.
\snippet examples/widgets/analogclock/analogclock.cpp 11
\snippet examples/widgets/analogclock/analogclock.cpp 12
\snippet examples/widgets/analogclock/analogclock.cpp 13
\snippet examples/widgets/analogclock/analogclock.cpp 14
The contents of custom widgets are drawn with a QPainter.
Painters can be used to draw on any QPaintDevice, but they are
usually used with widgets, so we pass the widget instance to the
painter's constructor.
We call QPainter::setRenderHint() with QPainter::Antialiasing to
turn on antialiasing. This makes drawing of diagonal lines much
smoother.
The translation moves the origin to the center of the widget, and
the scale operation ensures that the following drawing operations
are scaled to fit within the widget. We use a scale factor that
let's us use x and y coordinates between -100 and 100, and that
ensures that these lie within the length of the widget's shortest
side.
To make our code simpler, we will draw a fixed size clock face that will
be positioned and scaled so that it lies in the center of the widget.
The painter takes care of all the transformations made during the
paint event, and ensures that everything is drawn correctly. Letting
the painter handle transformations is often easier than performing
manual calculations just to draw the contents of a custom widget.
\img analogclock-viewport.png
We draw the hour hand first, using a formula that rotates the coordinate
system counterclockwise by a number of degrees determined by the current
hour and minute. This means that the hand will be shown rotated clockwise
by the required amount.
\snippet examples/widgets/analogclock/analogclock.cpp 15
\snippet examples/widgets/analogclock/analogclock.cpp 16
We set the pen to be Qt::NoPen because we don't want any outline,
and we use a solid brush with the color appropriate for
displaying hours. Brushes are used when filling in polygons and
other geometric shapes.
\snippet examples/widgets/analogclock/analogclock.cpp 17
\snippet examples/widgets/analogclock/analogclock.cpp 19
We save and restore the transformation matrix before and after the
rotation because we want to place the minute hand without having to
take into account any previous rotations.
\snippet examples/widgets/analogclock/analogclock.cpp 20
\codeline
\snippet examples/widgets/analogclock/analogclock.cpp 21
We draw markers around the edge of the clock for each hour. We
draw each marker then rotate the coordinate system so that the
painter is ready for the next one.
\snippet examples/widgets/analogclock/analogclock.cpp 22
\snippet examples/widgets/analogclock/analogclock.cpp 23
The minute hand is rotated in a similar way to the hour hand.
\snippet examples/widgets/analogclock/analogclock.cpp 25
\codeline
\snippet examples/widgets/analogclock/analogclock.cpp 26
Again, we draw markers around the edge of the clock, but this
time to indicate minutes. We skip multiples of 5 to avoid drawing
minute markers on top of hour markers.
*/
|