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