168 lines
7.1 KiB
Plaintext
168 lines
7.1 KiB
Plaintext
|
/****************************************************************************
|
||
|
**
|
||
|
** Copyright (C) 2011 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$
|
||
|
** No Commercial Usage
|
||
|
** This file contains pre-release code and may not be distributed.
|
||
|
** You may use this file in accordance with the terms and conditions
|
||
|
** contained in the Technology Preview License Agreement accompanying
|
||
|
** this package.
|
||
|
**
|
||
|
** 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.
|
||
|
**
|
||
|
** If you have questions regarding the use of this file, please contact
|
||
|
** Nokia at qt-info@nokia.com.
|
||
|
** $QT_END_LICENSE$
|
||
|
**
|
||
|
****************************************************************************/
|
||
|
|
||
|
/*!
|
||
|
\example widgets/wiggly
|
||
|
\title Wiggly Example
|
||
|
|
||
|
The Wiggly example shows how to animate a widget using
|
||
|
QBasicTimer and \l{QObject::timerEvent()}{timerEvent()}. In
|
||
|
addition, the example demonstrates how to use QFontMetrics to
|
||
|
determine the size of text on screen.
|
||
|
|
||
|
\image wiggly-example.png Screenshot of the Wiggly example
|
||
|
|
||
|
QBasicTimer is a low-level class for timers. Unlike QTimer,
|
||
|
QBasicTimer doesn't inherit from QObject; instead of emitting a
|
||
|
\l{QTimer::timeout()}{timeout()} signal when a certain amount of
|
||
|
time has passed, it sends a QTimerEvent to a QObject of our
|
||
|
choice. This makes QBasicTimer a more lightweight alternative to
|
||
|
QTimer. Qt's built-in widgets use it internally, and it is
|
||
|
provided in Qt's API for highly-optimized applications (e.g.,
|
||
|
\l{Qt for Embedded Linux} applications).
|
||
|
|
||
|
The example consists of two classes:
|
||
|
|
||
|
\list
|
||
|
\o \c WigglyWidget is the custom widget displaying the text
|
||
|
in a wiggly line.
|
||
|
|
||
|
\o \c Dialog is the dialog widget allowing the user to enter a
|
||
|
text. It combines a \c WigglyWidget and a \c QLineEdit.
|
||
|
\endlist
|
||
|
|
||
|
We will first take a quick look at the \c Dialog class, then we
|
||
|
will review the \c WigglyWidget class.
|
||
|
|
||
|
\section1 Dialog Class Definition
|
||
|
|
||
|
\snippet examples/widgets/wiggly/dialog.h 0
|
||
|
|
||
|
The \c Dialog class provides a dialog widget that allows the user
|
||
|
to enter a text. The text is then rendered by \c WigglyWidget.
|
||
|
|
||
|
\section1 Dialog Class Implementation
|
||
|
|
||
|
\snippet examples/widgets/wiggly/dialog.cpp 0
|
||
|
|
||
|
In the constructor we create a wiggly widget along with a
|
||
|
\l{QLineEdit}{line edit}, and we put the two widgets in a
|
||
|
vertical layout. We connect the line edit's \l
|
||
|
{QLineEdit::textChanged()}{textChanged()} signal to the wiggly
|
||
|
widget's \c setText() slot to obtain the real time interaction
|
||
|
with the wiggly widget. The widget's default text is "Hello
|
||
|
world!".
|
||
|
|
||
|
\section1 WigglyWidget Class Definition
|
||
|
|
||
|
\snippet examples/widgets/wiggly/wigglywidget.h 0
|
||
|
|
||
|
The \c WigglyWidget class provides the wiggly line displaying the
|
||
|
text. We subclass QWidget and reimplement the standard \l
|
||
|
{QWidget::paintEvent()}{paintEvent()} and \l
|
||
|
{QObject::timerEvent()}{timerEvent()} functions to draw and update
|
||
|
the widget. In addition we implement a public \c setText() slot
|
||
|
that sets the widget's text.
|
||
|
|
||
|
The \c timer variable, of type QBasicTimer, is used to update the
|
||
|
widget at regular intervals, making the widget move. The \c text
|
||
|
variable is used to store the currently displayed text, and \c
|
||
|
step to calculate position and color for each character on the
|
||
|
wiggly line.
|
||
|
|
||
|
\section1 WigglyWidget Class Implementation
|
||
|
|
||
|
\snippet examples/widgets/wiggly/wigglywidget.cpp 0
|
||
|
|
||
|
In the constructor, we make the widget's background slightly
|
||
|
lighter than the usual background using the QPalette::Midlight
|
||
|
color role. The background role defines the brush from the
|
||
|
widget's palette that Qt uses to paint the background. Then we
|
||
|
enlarge the widget's font with 20 points.
|
||
|
|
||
|
Finally we start the timer; the call to QBasicTimer::start()
|
||
|
makes sure that \e this particular wiggly widget will receive the
|
||
|
timer events generated when the timer times out (every 60
|
||
|
milliseconds).
|
||
|
|
||
|
\snippet examples/widgets/wiggly/wigglywidget.cpp 1
|
||
|
\snippet examples/widgets/wiggly/wigglywidget.cpp 2
|
||
|
|
||
|
The \c paintEvent() function is called whenever a QPaintEvent is
|
||
|
sent to the widget. Paint events are sent to widgets that need to
|
||
|
update themselves, for instance when part of a widget is exposed
|
||
|
because a covering widget was moved. For the wiggly widget, a
|
||
|
paint event will also be generated every 60 milliseconds from
|
||
|
the \c timerEvent() slot.
|
||
|
|
||
|
The \c sineTable represents y-values of the sine curve,
|
||
|
multiplied by 100. It is used to make the wiggly widget move
|
||
|
along the sine curve.
|
||
|
|
||
|
The QFontMetrics object provides information about the widget's
|
||
|
font. The \c x variable is the horizontal position where we start
|
||
|
drawing the text. The \c y variable is the vertical position of
|
||
|
the text's base line. Both variables are computed so that the
|
||
|
text is horizontally and vertically centered. To compute the base
|
||
|
line, we take into account the font's ascent (the height of the
|
||
|
font above the base line) and font's descent (the height of the
|
||
|
font below the base line). If the descent equals the ascent, they
|
||
|
cancel out each other and the base line is at \c height() / 2.
|
||
|
|
||
|
\snippet examples/widgets/wiggly/wigglywidget.cpp 3
|
||
|
\snippet examples/widgets/wiggly/wigglywidget.cpp 4
|
||
|
|
||
|
Each time the \c paintEvent() function is called, we create a
|
||
|
QPainter object \c painter to draw the contents of the widget.
|
||
|
For each character in \c text, we determine the color and the
|
||
|
position on the wiggly line based on \c step. In addition, \c x
|
||
|
is incremented by the character's width.
|
||
|
|
||
|
For simplicity, we assume that QFontMetrics::width(\c text)
|
||
|
returns the sum of the individual character widths
|
||
|
(QFontMetrics::width(\c text[i])). In practice, this is not
|
||
|
always the case because QFontMetrics::width(\c text) also takes
|
||
|
into account the kerning between certain letters (e.g., 'A' and
|
||
|
'V'). The result is that the text isn't perfectly centered. You
|
||
|
can verify this by typing "AVAVAVAVAVAV" in the line edit.
|
||
|
|
||
|
\snippet examples/widgets/wiggly/wigglywidget.cpp 5
|
||
|
\snippet examples/widgets/wiggly/wigglywidget.cpp 6
|
||
|
|
||
|
The \c timerEvent() function receives all the timer events that
|
||
|
are generated for this widget. If a timer event is sent from the
|
||
|
widget's QBasicTimer, we increment \c step to make the text move,
|
||
|
and call QWidget::update() to refresh the display. Any other
|
||
|
timer event is passed on to the base class's implementation of
|
||
|
the \l{QWidget::timerEvent()}{timerEvent()} function.
|
||
|
|
||
|
The QWidget::update() slot does not cause an immediate repaint;
|
||
|
instead the slot schedules a paint event for processing when Qt
|
||
|
returns to the main event loop. The paint events are then handled
|
||
|
by \c{WigglyWidget}'s \c paintEvent() function.
|
||
|
*/
|