Remove wiggly example
It demonstrates timerEvent() and some QFontMetrics There are other examples that demonstrates this Pick-to: 6.5 Change-Id: I4ad6f30c8ef93c995f980545ed88ab13b9aa9c7d Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
2db2eb600a
commit
e08575a18a
@ -178,7 +178,6 @@ manifestmeta.ios.names = "QtCore/Contiguous Cache Example" \
|
||||
"QtWidgets/Sliders Example" \
|
||||
"QtWidgets/Validators Example" \
|
||||
"QtWidgets/Window Flags Example" \
|
||||
"QtWidgets/Wiggly Example" \
|
||||
"QtQuick/Qt Quick Examples - Animation" \
|
||||
"QtQuick/Qt Quick Examples - Canvas" \
|
||||
"QtQuick/Qt Quick Examples - Drag and Drop" \
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 8.3 KiB |
@ -1,147 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||
|
||||
/*!
|
||||
\example widgets/wiggly
|
||||
\title Wiggly Example
|
||||
\ingroup examples-widgets
|
||||
\brief 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.
|
||||
|
||||
\borderedimage wiggly-example.png
|
||||
\caption 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 (such as
|
||||
embedded applications).
|
||||
|
||||
The example consists of two classes:
|
||||
|
||||
\list
|
||||
\li \c WigglyWidget is the custom widget displaying the text
|
||||
in a wiggly line.
|
||||
|
||||
\li \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 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 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!", with an emoji thrown in for fun.
|
||||
|
||||
\section1 WigglyWidget Class Definition
|
||||
|
||||
\snippet 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 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 widgets/wiggly/wigglywidget.cpp 1
|
||||
\snippet 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 widgets/wiggly/wigglywidget.cpp 3
|
||||
\snippet 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.
|
||||
Since we are going to paint the character symbols individually, we
|
||||
extract the unique unicode code point for each character from \c
|
||||
text, and convert it to a string \c symbol. For each \c symbol, we
|
||||
determine the color and the position on the wiggly line based on
|
||||
\c step and its \c offset from the start of the text. In addition,
|
||||
\c x is incremented by the symbol's width.
|
||||
|
||||
For simplicity, we assume that QFontMetrics::horizontalAdvance(\c text)
|
||||
returns the sum of the individual character advances
|
||||
(QFontMetrics::horizontalAdvance(\c symbol)). In practice, this is not
|
||||
always the case because QFontMetrics::horizontalAdvance(\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 widgets/wiggly/wigglywidget.cpp 5
|
||||
\snippet 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.
|
||||
*/
|
@ -26,5 +26,4 @@ qt_internal_add_example(tablet)
|
||||
qt_internal_add_example(tetrix)
|
||||
qt_internal_add_example(tooltips)
|
||||
qt_internal_add_example(validators)
|
||||
qt_internal_add_example(wiggly)
|
||||
qt_internal_add_example(windowflags)
|
||||
|
@ -21,5 +21,4 @@ SUBDIRS = analogclock \
|
||||
tetrix \
|
||||
tooltips \
|
||||
validators \
|
||||
wiggly \
|
||||
windowflags
|
||||
|
@ -1,38 +0,0 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(wiggly LANGUAGES CXX)
|
||||
|
||||
if(NOT DEFINED INSTALL_EXAMPLESDIR)
|
||||
set(INSTALL_EXAMPLESDIR "examples")
|
||||
endif()
|
||||
|
||||
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/wiggly")
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||
|
||||
qt_standard_project_setup()
|
||||
|
||||
qt_add_executable(wiggly
|
||||
dialog.cpp dialog.h
|
||||
main.cpp
|
||||
wigglywidget.cpp wigglywidget.h
|
||||
)
|
||||
|
||||
set_target_properties(wiggly PROPERTIES
|
||||
WIN32_EXECUTABLE TRUE
|
||||
MACOSX_BUNDLE TRUE
|
||||
)
|
||||
|
||||
target_link_libraries(wiggly PRIVATE
|
||||
Qt6::Core
|
||||
Qt6::Gui
|
||||
Qt6::Widgets
|
||||
)
|
||||
|
||||
install(TARGETS wiggly
|
||||
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
|
||||
)
|
@ -1,27 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "dialog.h"
|
||||
#include "wigglywidget.h"
|
||||
|
||||
#include <QLineEdit>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
//! [0]
|
||||
Dialog::Dialog(QWidget *parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
WigglyWidget *wigglyWidget = new WigglyWidget;
|
||||
QLineEdit *lineEdit = new QLineEdit;
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->addWidget(wigglyWidget);
|
||||
layout->addWidget(lineEdit);
|
||||
|
||||
connect(lineEdit, &QLineEdit::textChanged, wigglyWidget, &WigglyWidget::setText);
|
||||
lineEdit->setText(u8"🖖 " + tr("Hello world!"));
|
||||
|
||||
setWindowTitle(tr("Wiggly"));
|
||||
resize(360, 145);
|
||||
}
|
||||
//! [0]
|
@ -1,19 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef DIALOG_H
|
||||
#define DIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
//! [0]
|
||||
class Dialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Dialog(QWidget *parent = nullptr);
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
@ -1,16 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "dialog.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
Dialog dialog;
|
||||
dialog.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
QT += widgets
|
||||
|
||||
HEADERS = wigglywidget.h \
|
||||
dialog.h
|
||||
SOURCES = wigglywidget.cpp \
|
||||
dialog.cpp \
|
||||
main.cpp
|
||||
|
||||
# install
|
||||
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/wiggly
|
||||
INSTALLS += target
|
@ -1,65 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#include "wigglywidget.h"
|
||||
|
||||
#include <QFontMetrics>
|
||||
#include <QPainter>
|
||||
#include <QTimerEvent>
|
||||
|
||||
//! [0]
|
||||
WigglyWidget::WigglyWidget(QWidget *parent)
|
||||
: QWidget(parent), step(0)
|
||||
{
|
||||
setBackgroundRole(QPalette::Midlight);
|
||||
setAutoFillBackground(true);
|
||||
|
||||
QFont newFont = font();
|
||||
newFont.setPointSize(newFont.pointSize() + 20);
|
||||
setFont(newFont);
|
||||
|
||||
timer.start(60, this);
|
||||
}
|
||||
//! [0]
|
||||
|
||||
//! [1]
|
||||
void WigglyWidget::paintEvent(QPaintEvent * /* event */)
|
||||
//! [1] //! [2]
|
||||
{
|
||||
static constexpr int sineTable[16] = {
|
||||
0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38
|
||||
};
|
||||
|
||||
QFontMetrics metrics(font());
|
||||
int x = (width() - metrics.horizontalAdvance(text)) / 2;
|
||||
int y = (height() + metrics.ascent() - metrics.descent()) / 2;
|
||||
QColor color;
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
QPainter painter(this);
|
||||
//! [3] //! [4]
|
||||
int offset = 0;
|
||||
for (char32_t codePoint : text.toUcs4()) {
|
||||
int index = (step + offset++) % 16;
|
||||
color.setHsv((15 - index) * 16, 255, 191);
|
||||
painter.setPen(color);
|
||||
QString symbol = QString::fromUcs4(&codePoint, 1);
|
||||
painter.drawText(x, y - ((sineTable[index] * metrics.height()) / 400), symbol);
|
||||
x += metrics.horizontalAdvance(symbol);
|
||||
}
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
void WigglyWidget::timerEvent(QTimerEvent *event)
|
||||
//! [5] //! [6]
|
||||
{
|
||||
if (event->timerId() == timer.timerId()) {
|
||||
++step;
|
||||
update();
|
||||
} else {
|
||||
QWidget::timerEvent(event);
|
||||
}
|
||||
//! [6]
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
||||
|
||||
#ifndef WIGGLYWIDGET_H
|
||||
#define WIGGLYWIDGET_H
|
||||
|
||||
#include <QBasicTimer>
|
||||
#include <QWidget>
|
||||
|
||||
//! [0]
|
||||
class WigglyWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WigglyWidget(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void setText(const QString &newText) { text = newText; }
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void timerEvent(QTimerEvent *event) override;
|
||||
|
||||
private:
|
||||
QBasicTimer timer;
|
||||
QString text;
|
||||
int step;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
@ -36,7 +36,7 @@ QT_BEGIN_NAMESPACE
|
||||
The \l{widgets/wiggly}{Wiggly} example uses QBasicTimer to repaint
|
||||
a widget at regular intervals.
|
||||
|
||||
\sa QTimer, QTimerEvent, QObject::timerEvent(), Timers, {Wiggly Example}
|
||||
\sa QTimer, QTimerEvent, QObject::timerEvent(), Timers, {Affine Transformations}
|
||||
*/
|
||||
|
||||
|
||||
|
@ -105,7 +105,7 @@ QT_BEGIN_NAMESPACE
|
||||
used; Qt tries to work around these limitations.
|
||||
|
||||
\sa QBasicTimer, QTimerEvent, QObject::timerEvent(), Timers,
|
||||
{Analog Clock Example}, {Wiggly Example}
|
||||
{Analog Clock Example}, {Tetrix Example}
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
Loading…
Reference in New Issue
Block a user