summaryrefslogtreecommitdiffstats
path: root/examples/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'examples/widgets')
-rw-r--r--examples/widgets/doc/src/customsortfiltermodel.qdoc16
-rw-r--r--examples/widgets/doc/src/gradients.qdoc7
-rw-r--r--examples/widgets/graphicsview/boxes/glextensions.h15
-rw-r--r--examples/widgets/graphicsview/boxes/scene.cpp16
-rw-r--r--examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp17
-rw-r--r--examples/widgets/mainwindows/mainwindow/mainwindow.cpp1
-rw-r--r--examples/widgets/painting/deform/pathdeform.cpp11
-rw-r--r--examples/widgets/painting/gradients/gradients.cpp58
-rw-r--r--examples/widgets/painting/gradients/gradients.h7
-rw-r--r--examples/widgets/painting/gradients/gradients.html6
-rw-r--r--examples/widgets/richtext/calendar/mainwindow.cpp6
-rw-r--r--examples/widgets/richtext/textedit/example.html14
-rw-r--r--examples/widgets/richtext/textedit/textedit.cpp140
-rw-r--r--examples/widgets/tools/undo/main.cpp2
-rw-r--r--examples/widgets/touch/dials/dials.pro8
-rw-r--r--examples/widgets/touch/dials/dials.ui77
-rw-r--r--examples/widgets/touch/dials/doc/images/touch-dials-example.pngbin0 -> 17676 bytes
-rw-r--r--examples/widgets/touch/dials/doc/src/touch-dials.qdoc38
-rw-r--r--examples/widgets/touch/dials/main.cpp68
-rw-r--r--examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc42
-rw-r--r--examples/widgets/touch/fingerpaint/fingerpaint.pro13
-rw-r--r--examples/widgets/touch/fingerpaint/main.cpp61
-rw-r--r--examples/widgets/touch/fingerpaint/mainwindow.cpp227
-rw-r--r--examples/widgets/touch/fingerpaint/mainwindow.h98
-rw-r--r--examples/widgets/touch/fingerpaint/scribblearea.cpp235
-rw-r--r--examples/widgets/touch/fingerpaint/scribblearea.h90
-rw-r--r--examples/widgets/touch/knobs/doc/images/touch-knobs-example.pngbin0 -> 1290 bytes
-rw-r--r--examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc38
-rw-r--r--examples/widgets/touch/knobs/knob.cpp98
-rw-r--r--examples/widgets/touch/knobs/knob.h64
-rw-r--r--examples/widgets/touch/knobs/knobs.pro8
-rw-r--r--examples/widgets/touch/knobs/main.cpp74
-rw-r--r--examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.pngbin0 -> 42493 bytes
-rw-r--r--examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc38
-rw-r--r--examples/widgets/touch/pinchzoom/graphicsview.cpp95
-rw-r--r--examples/widgets/touch/pinchzoom/graphicsview.h65
-rw-r--r--examples/widgets/touch/pinchzoom/images/cheese.jpgbin0 -> 3029 bytes
-rw-r--r--examples/widgets/touch/pinchzoom/main.cpp95
-rw-r--r--examples/widgets/touch/pinchzoom/mice.qrc5
-rw-r--r--examples/widgets/touch/pinchzoom/mouse.cpp205
-rw-r--r--examples/widgets/touch/pinchzoom/mouse.h80
-rw-r--r--examples/widgets/touch/pinchzoom/pinchzoom.pro16
-rw-r--r--examples/widgets/touch/touch.pro4
-rw-r--r--examples/widgets/widgets.pro1
-rw-r--r--examples/widgets/widgets/tablet/mainwindow.cpp16
-rw-r--r--examples/widgets/widgets/tablet/mainwindow.h3
-rw-r--r--examples/widgets/widgets/tablet/tablet.pro5
-rw-r--r--examples/widgets/widgets/tablet/tabletcanvas.cpp12
-rw-r--r--examples/widgets/widgets/tablet/tabletcanvas.h1
49 files changed, 2097 insertions, 99 deletions
diff --git a/examples/widgets/doc/src/customsortfiltermodel.qdoc b/examples/widgets/doc/src/customsortfiltermodel.qdoc
index 6eab846e89..9f0d13dd83 100644
--- a/examples/widgets/doc/src/customsortfiltermodel.qdoc
+++ b/examples/widgets/doc/src/customsortfiltermodel.qdoc
@@ -121,14 +121,14 @@
\snippet itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 6
- We use QRegExp to define a pattern for the addresses we are looking
- for. The QRegExp::indexIn() function attempts to find a match in
- the given string and returns the position of the first match, or
- -1 if there was no match. If the given string contains the
- pattern, we use QRegExp's \l {QRegExp::cap()}{cap()} function to
- retrieve the actual address. The \l {QRegExp::cap()}{cap()}
- function returns the text captured by the \e nth
- subexpression. The entire match has index 0 and the parenthesized
+ We use QRegularExpression to define a pattern for the addresses we
+ are looking for. The \l {QRegularExpression::match()}{match()} function
+ returns a QRegularExpressionMatch object which contains the result of
+ the matching. If there is a match,
+ \l {QRegularExpressionMatch::hasMatch()}{hasMatch()} returns true. The
+ result of the match can be retrieved with QRegularExpressionMatch's
+ \l {QRegularExpressionMatch::captured()}{captured()} function.
+ The entire match has index 0 and the parenthesized
subexpressions have indexes starting from 1 (excluding
non-capturing parentheses).
diff --git a/examples/widgets/doc/src/gradients.qdoc b/examples/widgets/doc/src/gradients.qdoc
index 936bd2b014..457e6f837a 100644
--- a/examples/widgets/doc/src/gradients.qdoc
+++ b/examples/widgets/doc/src/gradients.qdoc
@@ -51,7 +51,12 @@
gradient. You can move points, and add new ones, by clicking with the left
mouse button, and remove points by clicking with the right button.
- There are three default configurations available at the bottom of
+ There are three example configurations available at the bottom of
the page that are provided as suggestions on how a color table could be
configured.
+
+ Qt also provides a suite of named gradient presets. They are based on the
+ free WebGradients collection. Click on the name in the Presets box to show
+ the gradient. Use the arrow buttons to browse through the available
+ presets.
*/
diff --git a/examples/widgets/graphicsview/boxes/glextensions.h b/examples/widgets/graphicsview/boxes/glextensions.h
index ac73e61641..685700d866 100644
--- a/examples/widgets/graphicsview/boxes/glextensions.h
+++ b/examples/widgets/graphicsview/boxes/glextensions.h
@@ -78,18 +78,11 @@ glMapBuffer
glUnmapBuffer
*/
-#ifndef Q_OS_MAC
-# ifndef APIENTRYP
-# ifdef APIENTRY
-# define APIENTRYP APIENTRY *
-# else
-# define APIENTRY
-# define APIENTRYP *
-# endif
-# endif
-#else
+#ifndef APIENTRY
# define APIENTRY
-# define APIENTRYP *
+#endif
+#ifndef APIENTRYP
+# define APIENTRYP APIENTRY *
#endif
#ifndef GL_VERSION_1_2
diff --git a/examples/widgets/graphicsview/boxes/scene.cpp b/examples/widgets/graphicsview/boxes/scene.cpp
index f51cad99ac..1637c1f781 100644
--- a/examples/widgets/graphicsview/boxes/scene.cpp
+++ b/examples/widgets/graphicsview/boxes/scene.cpp
@@ -952,17 +952,17 @@ void Scene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
return;
if (event->buttons() & Qt::LeftButton) {
- m_trackBalls[0].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[0].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
} else {
- m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
}
if (event->buttons() & Qt::RightButton) {
- m_trackBalls[1].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[1].move(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
} else {
- m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
}
if (event->buttons() & Qt::MidButton) {
@@ -980,12 +980,12 @@ void Scene::mousePressEvent(QGraphicsSceneMouseEvent *event)
return;
if (event->buttons() & Qt::LeftButton) {
- m_trackBalls[0].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[0].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
}
if (event->buttons() & Qt::RightButton) {
- m_trackBalls[1].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[1].push(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
}
@@ -1002,12 +1002,12 @@ void Scene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
return;
if (event->button() == Qt::LeftButton) {
- m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[0].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
}
if (event->button() == Qt::RightButton) {
- m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugate());
+ m_trackBalls[1].release(pixelPosToViewPos(event->scenePos()), m_trackBalls[2].rotation().conjugated());
event->accept();
}
diff --git a/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp b/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp
index c93368b390..35426657d9 100644
--- a/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp
+++ b/examples/widgets/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp
@@ -101,15 +101,20 @@ bool MySortFilterProxyModel::lessThan(const QModelIndex &left,
if (leftData.type() == QVariant::DateTime) {
return leftData.toDateTime() < rightData.toDateTime();
} else {
- static QRegExp emailPattern("[\\w\\.]*@[\\w\\.]*)");
+ static const QRegularExpression emailPattern("[\\w\\.]*@[\\w\\.]*");
QString leftString = leftData.toString();
- if(left.column() == 1 && emailPattern.indexIn(leftString) != -1)
- leftString = emailPattern.cap(1);
-
+ if (left.column() == 1) {
+ const QRegularExpressionMatch match = emailPattern.match(leftString);
+ if (match.hasMatch())
+ leftString = match.captured(0);
+ }
QString rightString = rightData.toString();
- if(right.column() == 1 && emailPattern.indexIn(rightString) != -1)
- rightString = emailPattern.cap(1);
+ if (right.column() == 1) {
+ const QRegularExpressionMatch match = emailPattern.match(rightString);
+ if (match.hasMatch())
+ rightString = match.captured(0);
+ }
return QString::localeAwareCompare(leftString, rightString) < 0;
}
diff --git a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp
index fe31207326..4ba180f312 100644
--- a/examples/widgets/mainwindows/mainwindow/mainwindow.cpp
+++ b/examples/widgets/mainwindows/mainwindow/mainwindow.cpp
@@ -97,6 +97,7 @@ MainWindow::MainWindow(const CustomSizeHintMap &customSizeHints,
QWidget *parent, Qt::WindowFlags flags)
: QMainWindow(parent, flags)
{
+ Q_UNUSED(message);
setObjectName("MainWindow");
setWindowTitle("Qt Main Window Example");
diff --git a/examples/widgets/painting/deform/pathdeform.cpp b/examples/widgets/painting/deform/pathdeform.cpp
index 490a8508d6..805804716f 100644
--- a/examples/widgets/painting/deform/pathdeform.cpp
+++ b/examples/widgets/painting/deform/pathdeform.cpp
@@ -50,7 +50,8 @@
#include "pathdeform.h"
-#include <QApplication>
+#include <QGuiApplication>
+#include <QScreen>
#include <QtDebug>
#include <QMouseEvent>
#include <QTimerEvent>
@@ -247,7 +248,7 @@ void PathDeformControls::layoutForSmallScreen()
deformSlider->setValue(80);
fontSizeSlider->setValue(120);
- QRect screen_size = QApplication::desktop()->screenGeometry();
+ QRect screen_size = QGuiApplication::primaryScreen()->geometry();
radiusSlider->setValue(qMin(screen_size.width(), screen_size.height())/5);
m_renderer->setText(tr("Qt"));
@@ -277,7 +278,7 @@ PathDeformWidget::PathDeformWidget(QWidget *parent, bool smallScreen)
connect(m_renderer, SIGNAL(clicked()), this, SLOT(showControls()));
connect(m_controls, SIGNAL(okPressed()), this, SLOT(hideControls()));
- connect(m_controls, SIGNAL(quitPressed()), QApplication::instance(), SLOT(quit()));
+ connect(m_controls, SIGNAL(quitPressed()), QCoreApplication::instance(), SLOT(quit()));
}
@@ -482,6 +483,10 @@ void PathDeformRenderer::timerEvent(QTimerEvent *e)
void PathDeformRenderer::mousePressEvent(QMouseEvent *e)
{
+ if (m_show_doc) {
+ setDescriptionEnabled(false);
+ return;
+ }
setDescriptionEnabled(false);
m_repaintTimer.stop();
diff --git a/examples/widgets/painting/gradients/gradients.cpp b/examples/widgets/painting/gradients/gradients.cpp
index 78c174a8bf..6d9f514a8d 100644
--- a/examples/widgets/painting/gradients/gradients.cpp
+++ b/examples/widgets/painting/gradients/gradients.cpp
@@ -301,8 +301,15 @@ GradientWidget::GradientWidget(QWidget *parent)
m_reflectSpreadButton = new QRadioButton(tr("Reflect Spread"), spreadGroup);
m_repeatSpreadButton = new QRadioButton(tr("Repeat Spread"), spreadGroup);
+ QGroupBox *presetsGroup = new QGroupBox(mainGroup);
+ presetsGroup->setTitle(tr("Presets"));
+ QPushButton *prevPresetButton = new QPushButton(tr("<"), presetsGroup);
+ m_presetButton = new QPushButton(tr("(unset)"), presetsGroup);
+ QPushButton *nextPresetButton = new QPushButton(tr(">"), presetsGroup);
+ updatePresetName();
+
QGroupBox *defaultsGroup = new QGroupBox(mainGroup);
- defaultsGroup->setTitle(tr("Defaults"));
+ defaultsGroup->setTitle(tr("Examples"));
QPushButton *default1Button = new QPushButton(tr("1"), defaultsGroup);
QPushButton *default2Button = new QPushButton(tr("2"), defaultsGroup);
QPushButton *default3Button = new QPushButton(tr("3"), defaultsGroup);
@@ -327,11 +334,12 @@ GradientWidget::GradientWidget(QWidget *parent)
mainLayout->addWidget(m_renderer);
mainLayout->addWidget(mainGroup);
- mainGroup->setFixedWidth(180);
+ mainGroup->setFixedWidth(200);
QVBoxLayout *mainGroupLayout = new QVBoxLayout(mainGroup);
mainGroupLayout->addWidget(editorGroup);
mainGroupLayout->addWidget(typeGroup);
mainGroupLayout->addWidget(spreadGroup);
+ mainGroupLayout->addWidget(presetsGroup);
mainGroupLayout->addWidget(defaultsGroup);
mainGroupLayout->addStretch(1);
mainGroupLayout->addWidget(showSourceButton);
@@ -353,6 +361,11 @@ GradientWidget::GradientWidget(QWidget *parent)
spreadGroupLayout->addWidget(m_repeatSpreadButton);
spreadGroupLayout->addWidget(m_reflectSpreadButton);
+ QHBoxLayout *presetsGroupLayout = new QHBoxLayout(presetsGroup);
+ presetsGroupLayout->addWidget(prevPresetButton);
+ presetsGroupLayout->addWidget(m_presetButton, 1);
+ presetsGroupLayout->addWidget(nextPresetButton);
+
QHBoxLayout *defaultsGroupLayout = new QHBoxLayout(defaultsGroup);
defaultsGroupLayout->addWidget(default1Button);
defaultsGroupLayout->addWidget(default2Button);
@@ -375,6 +388,13 @@ GradientWidget::GradientWidget(QWidget *parent)
connect(m_repeatSpreadButton, &QRadioButton::clicked,
m_renderer, &GradientRenderer::setRepeatSpread);
+ connect(prevPresetButton, &QPushButton::clicked,
+ this, &GradientWidget::setPrevPreset);
+ connect(m_presetButton, &QPushButton::clicked,
+ this, &GradientWidget::setPreset);
+ connect(nextPresetButton, &QPushButton::clicked,
+ this, &GradientWidget::setNextPreset);
+
connect(default1Button, &QPushButton::clicked,
this, &GradientWidget::setDefault1);
connect(default2Button, &QPushButton::clicked,
@@ -471,6 +491,40 @@ void GradientWidget::setDefault(int config)
m_renderer->setGradientStops(stops);
}
+void GradientWidget::updatePresetName()
+{
+ QMetaEnum presetEnum = QMetaEnum::fromType<QGradient::Preset>();
+ m_presetButton->setText(QLatin1String(presetEnum.key(m_presetIndex)));
+}
+
+void GradientWidget::changePresetBy(int indexOffset)
+{
+ QMetaEnum presetEnum = QMetaEnum::fromType<QGradient::Preset>();
+ m_presetIndex = qBound(0, m_presetIndex + indexOffset, presetEnum.keyCount() - 1);
+
+ QGradient::Preset preset = static_cast<QGradient::Preset>(presetEnum.value(m_presetIndex));
+ QGradient gradient(preset);
+ if (gradient.type() != QGradient::LinearGradient)
+ return;
+
+ QLinearGradient *linearGradientPointer = static_cast<QLinearGradient *>(&gradient);
+ QLineF objectStopsLine(linearGradientPointer->start(), linearGradientPointer->finalStop());
+ qreal scaleX = qFuzzyIsNull(objectStopsLine.dx()) ? 1.0 : (0.8 * m_renderer->width() / qAbs(objectStopsLine.dx()));
+ qreal scaleY = qFuzzyIsNull(objectStopsLine.dy()) ? 1.0 : (0.8 * m_renderer->height() / qAbs(objectStopsLine.dy()));
+ QLineF logicalStopsLine = QTransform::fromScale(scaleX, scaleY).map(objectStopsLine);
+ logicalStopsLine.translate(m_renderer->rect().center() - logicalStopsLine.center());
+ QPolygonF logicalStops;
+ logicalStops << logicalStopsLine.p1() << logicalStopsLine.p2();
+
+ m_linearButton->animateClick();
+ m_padSpreadButton->animateClick();
+ m_editor->setGradientStops(gradient.stops());
+ m_renderer->hoverPoints()->setPoints(logicalStops);
+ m_renderer->setGradientStops(gradient.stops());
+
+ updatePresetName();
+}
+
GradientRenderer::GradientRenderer(QWidget *parent)
: ArthurFrame(parent)
{
diff --git a/examples/widgets/painting/gradients/gradients.h b/examples/widgets/painting/gradients/gradients.h
index b4db298bb4..c6525d18f8 100644
--- a/examples/widgets/painting/gradients/gradients.h
+++ b/examples/widgets/painting/gradients/gradients.h
@@ -164,9 +164,14 @@ public slots:
void setDefault2() { setDefault(2); }
void setDefault3() { setDefault(3); }
void setDefault4() { setDefault(4); }
+ void setPreset() { changePresetBy(0); }
+ void setPrevPreset() { changePresetBy(-1); }
+ void setNextPreset() { changePresetBy(1); }
private:
void setDefault(int i);
+ void updatePresetName();
+ void changePresetBy(int indexOffset);
GradientRenderer *m_renderer;
GradientEditor *m_editor;
@@ -177,7 +182,9 @@ private:
QRadioButton *m_padSpreadButton;
QRadioButton *m_reflectSpreadButton;
QRadioButton *m_repeatSpreadButton;
+ QPushButton *m_presetButton;
+ int m_presetIndex = 0;
};
#endif // GRADIENTS_H
diff --git a/examples/widgets/painting/gradients/gradients.html b/examples/widgets/painting/gradients/gradients.html
index 1ea2c0ed6c..82c449035f 100644
--- a/examples/widgets/painting/gradients/gradients.html
+++ b/examples/widgets/painting/gradients/gradients.html
@@ -24,8 +24,12 @@ green and blue components while the last defines the alpha of the
gradient. You can move points, and add new ones, by clicking with the left
mouse button, and remove points by clicking with the right button.</p>
-<p>There are three default configurations available at the bottom of
+<p>There are three example configurations available at the bottom of
the page that are provided as suggestions on how a color table could be
configured.</p>
+<p>Qt also provides a suite of named gradient presets. They are based on the
+free WebGradients collection. Click on the name in the Presets box to show the
+gradient. Use the arrow buttons to browse through the available presets.</p>
+
</html>
diff --git a/examples/widgets/richtext/calendar/mainwindow.cpp b/examples/widgets/richtext/calendar/mainwindow.cpp
index 12c418e0b1..38dc0e2849 100644
--- a/examples/widgets/richtext/calendar/mainwindow.cpp
+++ b/examples/widgets/richtext/calendar/mainwindow.cpp
@@ -66,7 +66,7 @@ MainWindow::MainWindow()
QComboBox *monthCombo = new QComboBox;
for (int month = 1; month <= 12; ++month)
- monthCombo->addItem(QDate::longMonthName(month));
+ monthCombo->addItem(QLocale::system().monthName(month));
QDateTimeEdit *yearEdit = new QDateTimeEdit;
yearEdit->setDisplayFormat("yyyy");
@@ -168,7 +168,7 @@ void MainWindow::insertCalendar()
QTextTableCell cell = table->cellAt(0, weekDay-1);
//! [11] //! [12]
QTextCursor cellCursor = cell.firstCursorPosition();
- cellCursor.insertText(QString("%1").arg(QDate::longDayName(weekDay)), boldFormat);
+ cellCursor.insertText(QLocale::system().dayName(weekDay), boldFormat);
}
//! [12]
@@ -194,7 +194,7 @@ void MainWindow::insertCalendar()
cursor.endEditBlock();
//! [14]
setWindowTitle(tr("Calendar for %1 %2"
- ).arg(QDate::longMonthName(selectedDate.month())
+ ).arg(QLocale::system().monthName(selectedDate.month())
).arg(selectedDate.year()));
}
//! [14]
diff --git a/examples/widgets/richtext/textedit/example.html b/examples/widgets/richtext/textedit/example.html
index e3a56d1154..99090a697f 100644
--- a/examples/widgets/richtext/textedit/example.html
+++ b/examples/widgets/richtext/textedit/example.html
@@ -1,14 +1,14 @@
<html><head><meta name="qrichtext" content="1" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>QTextEdit Example</title><style type="text/css">
p, li { white-space: pre-wrap; }
</style></head><body style=" font-size:9pt; font-weight:400; font-style:normal; text-decoration:none;">
-<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:20pt; font-weight:600;">QTextEdit</span></p>
+<h1 align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:20pt; font-weight:600;">QTextEdit</span></h1>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">The QTextEdit widget is an advanced editor that supports formatted rich text. It can be used to display HTML and other rich document formats. Internally, QTextEdit uses the QTextDocument class to describe both the high-level structure of each document and the low-level formatting of paragraphs.</span></p>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;">If you are viewing this document in the <span style=" font-style:italic;">textedit</span> example, you can edit this document to explore Qt's rich text editing features. We have included some comments in each of the following sections to encourage you to experiment. </p>
-<p style=" margin-top:16px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:18pt; font-weight:600;"><span style=" font-size:16pt;">Font and Paragraph Styles</span></p>
+<h2 style=" margin-top:16px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:18pt; font-weight:600;"><span style=" font-size:16pt;">Font and Paragraph Styles</span></h2>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">QTextEdit supports </span><span style=" font-size:11pt; font-weight:600;">bold</span><span style=" font-size:11pt;">, </span><span style=" font-size:11pt; font-style:italic;">italic</span><span style=" font-size:11pt;">, and </span><span style=" font-size:11pt; text-decoration: underline;">underlined</span><span style=" font-size:11pt;"> font styles, and can display </span><span style=" font-size:11pt; font-weight:600; color:#00007f;">multicolored</span><span style=" font-size:11pt;"> </span><span style=" font-size:11pt; font-weight:600; color:#aa0000;">text</span><span style=" font-size:11pt;">. Font families such as </span><span style=" font-family:'Times New Roman'; font-size:11pt; font-weight:600;">Times New Roman</span><span style=" font-size:11pt;"> and </span><span style=" font-family:'Courier'; font-size:11pt; font-weight:600;">Courier</span><span style=" font-size:11pt;"> can also be used directly. </span><span style=" font-size:11pt; font-style:italic;">If you place the cursor in a region of styled text, the controls in the tool bars will change to reflect the current style.</span></p>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;">Paragraphs can be formatted so that the text is left-aligned, right-aligned, centered, or fully justified.</p>
<p align="center" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-style:italic;">Try changing the alignment of some text and resize the editor to see how the text layout changes.</span> </p>
-<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16pt; font-weight:600;">Lists</span></p>
+<h2 align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:16pt; font-weight:600;">Lists</span></h2>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:16pt; font-weight:600;"><span style=" font-size:11pt; font-weight:400;">Different kinds of lists can be included in rich text documents. Standard bullet lists can be nested, using different symbols for each level of the list: </span></p>
<ul style="-qt-list-indent: 1;"><li style=" font-size:11pt;" style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Disc symbols are typically used for top-level list items. </li></ul>
<ul type=circle style="-qt-list-indent: 2;"><li style=" font-size:11pt;" style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Circle symbols can be used to distinguish between items in lower-level lists.</li></ul>
@@ -24,10 +24,10 @@ p, li { white-space: pre-wrap; }
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p>
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;">The list will automatically be renumbered if you add or remove items. <span style=" font-style:italic;">Try adding new sections to the above list or removing existing item to see the numbers change.</span> </p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p>
-<p style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Images</span></p>
+<h2 style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Images</span></h2>
<p style=" margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:16pt; font-weight:600;"><span style=" font-size:11pt; font-weight:400;">Inline images are treated like ordinary ranges of characters in the text editor, so they flow with the surrounding text. Images can also be selected in the same way as text, making it easy to cut, copy, and paste them. </span></p>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><img src=":/images/logo32.png" /><span style=" font-style:italic;"> Try to select this image by clicking and dragging over it with the mouse, or use the text cursor to select it by holding down Shift and using the arrow keys. You can then cut or copy it, and paste it into different parts of this document.</span></p>
-<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Tables</span></p>
+<h2 align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Tables</span></h2>
<p align="justify" style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:16pt; font-weight:600;"><span style=" font-size:11pt; font-weight:400;">QTextEdit can arrange and format tables, supporting features such as row and column spans, text formatting within cells, and size constraints for columns. </span></p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p>
@@ -72,8 +72,8 @@ p, li { white-space: pre-wrap; }
<td></td></tr></table>
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"></p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt; font-style:italic;">Try adding text to the cells in the table and experiment with the alignment of the paragraphs.</p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Hyperlinks</span></p>
+<h2 style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Hyperlinks</span></h2>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:11pt;">QTextEdit is designed to support hyperlinks between documents, and this feature is used extensively in </span><span style=" font-size:11pt; font-style:italic;">Qt Assistant</span><span style=" font-size:11pt;">. Hyperlinks are automatically created when an HTML file is imported into an editor. Since the rich text framework supports hyperlinks natively, they can also be created programatically.</span></p>
-<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Undo and Redo</span></p>
+<h2 style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-size:16pt; font-weight:600;">Undo and Redo</span></h2>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;">Full support for undo and redo operations is built into QTextEdit and the underlying rich text framework. Operations on a document can be packaged together to make editing a more comfortable experience for the user.</p>
<p style=" margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:11pt;"><span style=" font-style:italic;">Try making changes to this document and press Ctrl+Z to undo them. You can always recover the original contents of the document.</span> </p></body></html>
diff --git a/examples/widgets/richtext/textedit/textedit.cpp b/examples/widgets/richtext/textedit/textedit.cpp
index fe4ee4f499..0d51ce61ad 100644
--- a/examples/widgets/richtext/textedit/textedit.cpp
+++ b/examples/widgets/richtext/textedit/textedit.cpp
@@ -141,13 +141,23 @@ TextEdit::TextEdit(QWidget *parent)
#ifndef QT_NO_CLIPBOARD
actionCut->setEnabled(false);
+ connect(textEdit, &QTextEdit::copyAvailable, actionCut, &QAction::setEnabled);
actionCopy->setEnabled(false);
+ connect(textEdit, &QTextEdit::copyAvailable, actionCopy, &QAction::setEnabled);
connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &TextEdit::clipboardDataChanged);
#endif
textEdit->setFocus();
setCurrentFileName(QString());
+
+#ifdef Q_OS_MACOS
+ // Use dark text on light background on macOS, also in dark mode.
+ QPalette pal = textEdit->palette();
+ pal.setColor(QPalette::Base, QColor(Qt::white));
+ pal.setColor(QPalette::Text, QColor(Qt::black));
+ textEdit->setPalette(pal);
+#endif
}
void TextEdit::closeEvent(QCloseEvent *e)
@@ -348,6 +358,12 @@ void TextEdit::setupTextActions()
comboStyle->addItem("Ordered List (Alpha upper)");
comboStyle->addItem("Ordered List (Roman lower)");
comboStyle->addItem("Ordered List (Roman upper)");
+ comboStyle->addItem("Heading 1");
+ comboStyle->addItem("Heading 2");
+ comboStyle->addItem("Heading 3");
+ comboStyle->addItem("Heading 4");
+ comboStyle->addItem("Heading 5");
+ comboStyle->addItem("Heading 6");
connect(comboStyle, QOverload<int>::of(&QComboBox::activated), this, &TextEdit::textStyle);
@@ -575,44 +591,56 @@ void TextEdit::textSize(const QString &p)
void TextEdit::textStyle(int styleIndex)
{
QTextCursor cursor = textEdit->textCursor();
+ QTextListFormat::Style style = QTextListFormat::ListStyleUndefined;
+
+ switch (styleIndex) {
+ case 1:
+ style = QTextListFormat::ListDisc;
+ break;
+ case 2:
+ style = QTextListFormat::ListCircle;
+ break;
+ case 3:
+ style = QTextListFormat::ListSquare;
+ break;
+ case 4:
+ style = QTextListFormat::ListDecimal;
+ break;
+ case 5:
+ style = QTextListFormat::ListLowerAlpha;
+ break;
+ case 6:
+ style = QTextListFormat::ListUpperAlpha;
+ break;
+ case 7:
+ style = QTextListFormat::ListLowerRoman;
+ break;
+ case 8:
+ style = QTextListFormat::ListUpperRoman;
+ break;
+ default:
+ break;
+ }
- if (styleIndex != 0) {
- QTextListFormat::Style style = QTextListFormat::ListDisc;
-
- switch (styleIndex) {
- default:
- case 1:
- style = QTextListFormat::ListDisc;
- break;
- case 2:
- style = QTextListFormat::ListCircle;
- break;
- case 3:
- style = QTextListFormat::ListSquare;
- break;
- case 4:
- style = QTextListFormat::ListDecimal;
- break;
- case 5:
- style = QTextListFormat::ListLowerAlpha;
- break;
- case 6:
- style = QTextListFormat::ListUpperAlpha;
- break;
- case 7:
- style = QTextListFormat::ListLowerRoman;
- break;
- case 8:
- style = QTextListFormat::ListUpperRoman;
- break;
- }
+ cursor.beginEditBlock();
- cursor.beginEditBlock();
+ QTextBlockFormat blockFmt = cursor.blockFormat();
- QTextBlockFormat blockFmt = cursor.blockFormat();
+ if (style == QTextListFormat::ListStyleUndefined) {
+ blockFmt.setObjectIndex(-1);
+ int headingLevel = styleIndex >= 9 ? styleIndex - 9 + 1 : 0; // H1 to H6, or Standard
+ blockFmt.setHeadingLevel(headingLevel);
+ cursor.setBlockFormat(blockFmt);
+ int sizeAdjustment = headingLevel ? 4 - headingLevel : 0; // H1 to H6: +3 to -2
+ QTextCharFormat fmt;
+ fmt.setFontWeight(headingLevel ? QFont::Bold : QFont::Normal);
+ fmt.setProperty(QTextFormat::FontSizeAdjustment, sizeAdjustment);
+ cursor.select(QTextCursor::LineUnderCursor);
+ cursor.mergeCharFormat(fmt);
+ textEdit->mergeCurrentCharFormat(fmt);
+ } else {
QTextListFormat listFmt;
-
if (cursor.currentList()) {
listFmt = cursor.currentList()->format();
} else {
@@ -620,18 +648,11 @@ void TextEdit::textStyle(int styleIndex)
blockFmt.setIndent(0);
cursor.setBlockFormat(blockFmt);
}
-
listFmt.setStyle(style);
-
cursor.createList(listFmt);
-
- cursor.endEditBlock();
- } else {
- // ####
- QTextBlockFormat bfmt;
- bfmt.setObjectIndex(-1);
- cursor.mergeBlockFormat(bfmt);
}
+
+ cursor.endEditBlock();
}
void TextEdit::textColor()
@@ -666,6 +687,41 @@ void TextEdit::currentCharFormatChanged(const QTextCharFormat &format)
void TextEdit::cursorPositionChanged()
{
alignmentChanged(textEdit->alignment());
+ QTextList *list = textEdit->textCursor().currentList();
+ if (list) {
+ switch (list->format().style()) {
+ case QTextListFormat::ListDisc:
+ comboStyle->setCurrentIndex(1);
+ break;
+ case QTextListFormat::ListCircle:
+ comboStyle->setCurrentIndex(2);
+ break;
+ case QTextListFormat::ListSquare:
+ comboStyle->setCurrentIndex(3);
+ break;
+ case QTextListFormat::ListDecimal:
+ comboStyle->setCurrentIndex(4);
+ break;
+ case QTextListFormat::ListLowerAlpha:
+ comboStyle->setCurrentIndex(5);
+ break;
+ case QTextListFormat::ListUpperAlpha:
+ comboStyle->setCurrentIndex(6);
+ break;
+ case QTextListFormat::ListLowerRoman:
+ comboStyle->setCurrentIndex(7);
+ break;
+ case QTextListFormat::ListUpperRoman:
+ comboStyle->setCurrentIndex(8);
+ break;
+ default:
+ comboStyle->setCurrentIndex(-1);
+ break;
+ }
+ } else {
+ int headingLevel = textEdit->textCursor().blockFormat().headingLevel();
+ comboStyle->setCurrentIndex(headingLevel ? headingLevel + 8 : 0);
+ }
}
void TextEdit::clipboardDataChanged()
diff --git a/examples/widgets/tools/undo/main.cpp b/examples/widgets/tools/undo/main.cpp
index eff44ca3e8..a5ec1b1b83 100644
--- a/examples/widgets/tools/undo/main.cpp
+++ b/examples/widgets/tools/undo/main.cpp
@@ -62,4 +62,4 @@ int main(int argc, char **argv)
win.show();
return app.exec();
-};
+}
diff --git a/examples/widgets/touch/dials/dials.pro b/examples/widgets/touch/dials/dials.pro
new file mode 100644
index 0000000000..0e823551cc
--- /dev/null
+++ b/examples/widgets/touch/dials/dials.pro
@@ -0,0 +1,8 @@
+QT += widgets
+
+SOURCES += main.cpp
+FORMS += dials.ui
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/dials
+INSTALLS += target
diff --git a/examples/widgets/touch/dials/dials.ui b/examples/widgets/touch/dials/dials.ui
new file mode 100644
index 0000000000..8ca7ae9475
--- /dev/null
+++ b/examples/widgets/touch/dials/dials.ui
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>Dials</class>
+ <widget class="QWidget" name="Dials">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QDial" name="dial_1">
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QDial" name="dial_2">
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QDial" name="dial_3">
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QDial" name="dial_4">
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QDial" name="dial_5">
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDial" name="dial_6">
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QDial" name="dial_7">
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QDial" name="dial_8">
+ <property name="notchesVisible">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/widgets/touch/dials/doc/images/touch-dials-example.png b/examples/widgets/touch/dials/doc/images/touch-dials-example.png
new file mode 100644
index 0000000000..60e1776fc3
--- /dev/null
+++ b/examples/widgets/touch/dials/doc/images/touch-dials-example.png
Binary files differ
diff --git a/examples/widgets/touch/dials/doc/src/touch-dials.qdoc b/examples/widgets/touch/dials/doc/src/touch-dials.qdoc
new file mode 100644
index 0000000000..dec8248efb
--- /dev/null
+++ b/examples/widgets/touch/dials/doc/src/touch-dials.qdoc
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example touch/dials
+ \title Touch Dials Example
+ \ingroup touchinputexamples
+ \brief Shows how to apply touch to a set of standard Qt widgets.
+
+ The Touch Dials example shows how to apply touch to a set of
+ standard Qt widgets.
+
+ \image touch-dials-example.png
+*/
diff --git a/examples/widgets/touch/dials/main.cpp b/examples/widgets/touch/dials/main.cpp
new file mode 100644
index 0000000000..071f485de3
--- /dev/null
+++ b/examples/widgets/touch/dials/main.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QWidget>
+#include <QDial>
+
+#include "ui_dials.h"
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QWidget window;
+ Ui::Dials dialsUi;
+ dialsUi.setupUi(&window);
+ QList<QAbstractSlider *> sliders = window.findChildren<QAbstractSlider *>();
+ foreach (QAbstractSlider *slider, sliders)
+ slider->setAttribute(Qt::WA_AcceptTouchEvents);
+ window.showMaximized();
+ return app.exec();
+}
diff --git a/examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc b/examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc
new file mode 100644
index 0000000000..6f8f636f86
--- /dev/null
+++ b/examples/widgets/touch/fingerpaint/doc/src/fingerpaint.qdoc
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example touch/fingerpaint
+ \title Finger Paint Example
+ \ingroup touchinputexamples
+ \brief Shows the use of a touchscreen to make a simple painting application.
+
+ The Finger Paint example shows the use of a touchscreen with a custom widget
+ to create a simple painting application.
+
+ \image touch-fingerpaint-example.png
+
+ This example was specifically designed to work with a touchscreen, using
+ QTouchEvent instead of QMouseEvent to handle user input over the custom
+ widget. As a result, it is not possible to draw with the mouse cursor.
+*/
diff --git a/examples/widgets/touch/fingerpaint/fingerpaint.pro b/examples/widgets/touch/fingerpaint/fingerpaint.pro
new file mode 100644
index 0000000000..6370da6607
--- /dev/null
+++ b/examples/widgets/touch/fingerpaint/fingerpaint.pro
@@ -0,0 +1,13 @@
+QT += widgets
+requires(qtConfig(filedialog))
+qtHaveModule(printsupport): QT += printsupport
+
+HEADERS = mainwindow.h \
+ scribblearea.h
+SOURCES = main.cpp \
+ mainwindow.cpp \
+ scribblearea.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/fingerpaint
+INSTALLS += target
diff --git a/examples/widgets/touch/fingerpaint/main.cpp b/examples/widgets/touch/fingerpaint/main.cpp
new file mode 100644
index 0000000000..e7ab8856b7
--- /dev/null
+++ b/examples/widgets/touch/fingerpaint/main.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ MainWindow window;
+ window.showMaximized();
+ return app.exec();
+}
diff --git a/examples/widgets/touch/fingerpaint/mainwindow.cpp b/examples/widgets/touch/fingerpaint/mainwindow.cpp
new file mode 100644
index 0000000000..0e45eea240
--- /dev/null
+++ b/examples/widgets/touch/fingerpaint/mainwindow.cpp
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+
+#include "mainwindow.h"
+#include "scribblearea.h"
+
+//! [0]
+MainWindow::MainWindow()
+{
+ scribbleArea = new ScribbleArea;
+ setCentralWidget(scribbleArea);
+
+ createActions();
+ createMenus();
+
+ setWindowTitle(tr("Finger Paint"));
+ resize(500, 500);
+}
+//! [0]
+
+//! [1]
+void MainWindow::closeEvent(QCloseEvent *event)
+//! [1] //! [2]
+{
+ if (maybeSave()) {
+ event->accept();
+ } else {
+ event->ignore();
+ }
+}
+//! [2]
+
+//! [3]
+void MainWindow::open()
+//! [3] //! [4]
+{
+ if (maybeSave()) {
+ QString fileName = QFileDialog::getOpenFileName(this,
+ tr("Open File"), QDir::currentPath());
+ if (!fileName.isEmpty())
+ scribbleArea->openImage(fileName);
+ }
+}
+//! [4]
+
+//! [5]
+void MainWindow::save()
+//! [5] //! [6]
+{
+ QAction *action = qobject_cast<QAction *>(sender());
+ QByteArray fileFormat = action->data().toByteArray();
+ saveFile(fileFormat);
+}
+//! [6]
+
+//! [11]
+void MainWindow::about()
+//! [11] //! [12]
+{
+ QMessageBox::about(this, tr("About Scribble"),
+ tr("<p>The <b>Scribble</b> example shows how to use QMainWindow as the "
+ "base widget for an application, and how to reimplement some of "
+ "QWidget's event handlers to receive the events generated for "
+ "the application's widgets:</p><p> We reimplement the mouse event "
+ "handlers to facilitate drawing, the paint event handler to "
+ "update the application and the resize event handler to optimize "
+ "the application's appearance. In addition we reimplement the "
+ "close event handler to intercept the close events before "
+ "terminating the application.</p><p> The example also demonstrates "
+ "how to use QPainter to draw an image in real time, as well as "
+ "to repaint widgets.</p>"));
+}
+//! [12]
+
+//! [13]
+void MainWindow::createActions()
+//! [13] //! [14]
+{
+ openAct = new QAction(tr("&Open..."), this);
+ openAct->setShortcut(tr("Ctrl+O"));
+ connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
+
+ foreach (QByteArray format, QImageWriter::supportedImageFormats()) {
+ QString text = tr("%1...").arg(QString(format).toUpper());
+
+ QAction *action = new QAction(text, this);
+ action->setData(format);
+ connect(action, SIGNAL(triggered()), this, SLOT(save()));
+ saveAsActs.append(action);
+ }
+
+ printAct = new QAction(tr("&Print..."), this);
+ connect(printAct, SIGNAL(triggered()), scribbleArea, SLOT(print()));
+
+ exitAct = new QAction(tr("E&xit"), this);
+ exitAct->setShortcut(tr("Ctrl+Q"));
+ connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
+
+ clearScreenAct = new QAction(tr("&Clear Screen"), this);
+ clearScreenAct->setShortcut(tr("Ctrl+L"));
+ connect(clearScreenAct, SIGNAL(triggered()),
+ scribbleArea, SLOT(clearImage()));
+
+ aboutAct = new QAction(tr("&About"), this);
+ connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
+
+ aboutQtAct = new QAction(tr("About &Qt"), this);
+ connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
+}
+//! [14]
+
+//! [15]
+void MainWindow::createMenus()
+//! [15] //! [16]
+{
+ saveAsMenu = new QMenu(tr("&Save As"), this);
+ foreach (QAction *action, saveAsActs)
+ saveAsMenu->addAction(action);
+
+ fileMenu = new QMenu(tr("&File"), this);
+ fileMenu->addAction(openAct);
+ fileMenu->addMenu(saveAsMenu);
+ fileMenu->addAction(printAct);
+ fileMenu->addSeparator();
+ fileMenu->addAction(exitAct);
+
+ optionMenu = new QMenu(tr("&Options"), this);
+ optionMenu->addAction(clearScreenAct);
+
+ helpMenu = new QMenu(tr("&Help"), this);
+ helpMenu->addAction(aboutAct);
+ helpMenu->addAction(aboutQtAct);
+
+ menuBar()->addMenu(fileMenu);
+ menuBar()->addMenu(optionMenu);
+ menuBar()->addMenu(helpMenu);
+}
+//! [16]
+
+//! [17]
+bool MainWindow::maybeSave()
+//! [17] //! [18]
+{
+ if (scribbleArea->isModified()) {
+ QMessageBox::StandardButton ret;
+ ret = QMessageBox::warning(this, tr("Scribble"),
+ tr("The image has been modified.\n"
+ "Do you want to save your changes?"),
+ QMessageBox::Save | QMessageBox::Discard
+ | QMessageBox::Cancel);
+ if (ret == QMessageBox::Save) {
+ return saveFile("png");
+ } else if (ret == QMessageBox::Cancel) {
+ return false;
+ }
+ }
+ return true;
+}
+//! [18]
+
+//! [19]
+bool MainWindow::saveFile(const QByteArray &fileFormat)
+//! [19] //! [20]
+{
+ QString initialPath = QDir::currentPath() + "/untitled." + fileFormat;
+
+ QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"),
+ initialPath,
+ tr("%1 Files (*.%2);;All Files (*)")
+ .arg(QString::fromLatin1(fileFormat.toUpper()))
+ .arg(QString::fromLatin1(fileFormat)));
+ if (fileName.isEmpty()) {
+ return false;
+ } else {
+ return scribbleArea->saveImage(fileName, fileFormat.constData());
+ }
+}
+//! [20]
diff --git a/examples/widgets/touch/fingerpaint/mainwindow.h b/examples/widgets/touch/fingerpaint/mainwindow.h
new file mode 100644
index 0000000000..47c339050e
--- /dev/null
+++ b/examples/widgets/touch/fingerpaint/mainwindow.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QList>
+#include <QMainWindow>
+
+class ScribbleArea;
+
+//! [0]
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow();
+
+protected:
+ void closeEvent(QCloseEvent *event) override;
+
+private slots:
+ void open();
+ void save();
+ void about();
+
+private:
+ void createActions();
+ void createMenus();
+ bool maybeSave();
+ bool saveFile(const QByteArray &fileFormat);
+
+ ScribbleArea *scribbleArea;
+
+ QMenu *saveAsMenu;
+ QMenu *fileMenu;
+ QMenu *optionMenu;
+ QMenu *helpMenu;
+
+ QAction *openAct;
+ QList<QAction *> saveAsActs;
+ QAction *exitAct;
+ QAction *printAct;
+ QAction *clearScreenAct;
+ QAction *aboutAct;
+ QAction *aboutQtAct;
+};
+//! [0]
+
+#endif
diff --git a/examples/widgets/touch/fingerpaint/scribblearea.cpp b/examples/widgets/touch/fingerpaint/scribblearea.cpp
new file mode 100644
index 0000000000..aa4e60c934
--- /dev/null
+++ b/examples/widgets/touch/fingerpaint/scribblearea.cpp
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets>
+#if defined(QT_PRINTSUPPORT_LIB)
+#include <QtPrintSupport/qtprintsupportglobal.h>
+#if QT_CONFIG(printdialog)
+#include <QPrinter>
+#include <QPrintDialog>
+#endif
+#endif
+
+#include "scribblearea.h"
+
+static const qreal MinimumDiameter = 3.0;
+static const qreal MaximumDiameter = 50.0;
+
+//! [0]
+ScribbleArea::ScribbleArea(QWidget *parent)
+ : QWidget(parent)
+{
+ setAttribute(Qt::WA_AcceptTouchEvents);
+ setAttribute(Qt::WA_StaticContents);
+ modified = false;
+
+ myPenColors
+ << QColor("green")
+ << QColor("purple")
+ << QColor("red")
+ << QColor("blue")
+ << QColor("yellow")
+
+ << QColor("pink")
+ << QColor("orange")
+ << QColor("brown")
+ << QColor("grey")
+ << QColor("black");
+}
+//! [0]
+
+//! [1]
+bool ScribbleArea::openImage(const QString &fileName)
+//! [1] //! [2]
+{
+ QImage loadedImage;
+ if (!loadedImage.load(fileName))
+ return false;
+
+ QSize newSize = loadedImage.size().expandedTo(size());
+ resizeImage(&loadedImage, newSize);
+ image = loadedImage;
+ modified = false;
+ update();
+ return true;
+}
+//! [2]
+
+//! [3]
+bool ScribbleArea::saveImage(const QString &fileName, const char *fileFormat)
+//! [3] //! [4]
+{
+ QImage visibleImage = image;
+ resizeImage(&visibleImage, size());
+
+ if (visibleImage.save(fileName, fileFormat)) {
+ modified = false;
+ return true;
+ } else {
+ return false;
+ }
+}
+//! [4]
+
+//! [9]
+void ScribbleArea::clearImage()
+//! [9] //! [10]
+{
+ image.fill(qRgb(255, 255, 255));
+ modified = true;
+ update();
+}
+//! [10]
+
+//! [12] //! [13]
+void ScribbleArea::paintEvent(QPaintEvent *event)
+//! [13] //! [14]
+{
+ QPainter painter(this);
+ const QRect rect = event->rect();
+ painter.drawImage(rect.topLeft(), image, rect);
+}
+//! [14]
+
+//! [15]
+void ScribbleArea::resizeEvent(QResizeEvent *event)
+//! [15] //! [16]
+{
+ if (width() > image.width() || height() > image.height()) {
+ int newWidth = qMax(width() + 128, image.width());
+ int newHeight = qMax(height() + 128, image.height());
+ resizeImage(&image, QSize(newWidth, newHeight));
+ update();
+ }
+ QWidget::resizeEvent(event);
+}
+//! [16]
+
+//! [19]
+void ScribbleArea::resizeImage(QImage *image, const QSize &newSize)
+//! [19] //! [20]
+{
+ if (image->size() == newSize)
+ return;
+
+ QImage newImage(newSize, QImage::Format_RGB32);
+ newImage.fill(qRgb(255, 255, 255));
+ QPainter painter(&newImage);
+ painter.drawImage(QPoint(0, 0), *image);
+ *image = newImage;
+}
+//! [20]
+
+//! [21]
+void ScribbleArea::print()
+{
+#if QT_CONFIG(printdialog)
+ QPrinter printer(QPrinter::HighResolution);
+
+ QPrintDialog printDialog(&printer, this);
+//! [21] //! [22]
+ if (printDialog.exec() == QDialog::Accepted) {
+ QPainter painter(&printer);
+ QRect rect = painter.viewport();
+ QSize size = image.size();
+ size.scale(rect.size(), Qt::KeepAspectRatio);
+ painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
+ painter.setWindow(image.rect());
+ painter.drawImage(0, 0, image);
+ }
+#endif // QT_CONFIG(printdialog)
+}
+//! [22]
+
+bool ScribbleArea::event(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ {
+ QTouchEvent *touch = static_cast<QTouchEvent *>(event);
+ QList<QTouchEvent::TouchPoint> touchPoints = static_cast<QTouchEvent *>(event)->touchPoints();
+ foreach (const QTouchEvent::TouchPoint &touchPoint, touchPoints) {
+ switch (touchPoint.state()) {
+ case Qt::TouchPointStationary:
+ case Qt::TouchPointReleased:
+ // don't do anything if this touch point hasn't moved or has been released
+ continue;
+ default:
+ {
+ QRectF rect = touchPoint.rect();
+ if (rect.isEmpty()) {
+ qreal diameter = MaximumDiameter;
+ if (touch->device()->capabilities() & QTouchDevice::Pressure)
+ diameter = MinimumDiameter + (MaximumDiameter - MinimumDiameter) * touchPoint.pressure();
+ rect.setSize(QSizeF(diameter, diameter));
+ }
+
+ QPainter painter(&image);
+ painter.setPen(Qt::NoPen);
+ painter.setBrush(myPenColors.at(touchPoint.id() % myPenColors.count()));
+ painter.drawEllipse(rect);
+ painter.end();
+
+ modified = true;
+ int rad = 2;
+ update(rect.toRect().adjusted(-rad,-rad, +rad, +rad));
+ }
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ return QWidget::event(event);
+ }
+ return true;
+}
diff --git a/examples/widgets/touch/fingerpaint/scribblearea.h b/examples/widgets/touch/fingerpaint/scribblearea.h
new file mode 100644
index 0000000000..5138e3a1ab
--- /dev/null
+++ b/examples/widgets/touch/fingerpaint/scribblearea.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCRIBBLEAREA_H
+#define SCRIBBLEAREA_H
+
+#include <QColor>
+#include <QImage>
+#include <QPoint>
+#include <QWidget>
+
+//! [0]
+class ScribbleArea : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ScribbleArea(QWidget *parent = 0);
+
+ bool openImage(const QString &fileName);
+ bool saveImage(const QString &fileName, const char *fileFormat);
+
+ bool isModified() const { return modified; }
+
+public slots:
+ void clearImage();
+ void print();
+
+protected:
+ void paintEvent(QPaintEvent *event) override;
+ void resizeEvent(QResizeEvent *event) override;
+ bool event(QEvent *event) override;
+
+private:
+ void resizeImage(QImage *image, const QSize &newSize);
+
+ bool modified;
+ QList<QColor> myPenColors;
+ QImage image;
+};
+//! [0]
+
+#endif
diff --git a/examples/widgets/touch/knobs/doc/images/touch-knobs-example.png b/examples/widgets/touch/knobs/doc/images/touch-knobs-example.png
new file mode 100644
index 0000000000..1cbd90d101
--- /dev/null
+++ b/examples/widgets/touch/knobs/doc/images/touch-knobs-example.png
Binary files differ
diff --git a/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc b/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc
new file mode 100644
index 0000000000..6da5992195
--- /dev/null
+++ b/examples/widgets/touch/knobs/doc/src/touch-knobs.qdoc
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example touch/knobs
+ \title Touch Knobs Example
+ \ingroup touchinputexamples
+ \brief Shows how to create custom controls that accept touch input.
+
+ The Touch Knobs example shows how to create custom controls that
+ accept touch input.
+
+ \image touch-knobs-example.png
+*/
diff --git a/examples/widgets/touch/knobs/knob.cpp b/examples/widgets/touch/knobs/knob.cpp
new file mode 100644
index 0000000000..12aaa1e948
--- /dev/null
+++ b/examples/widgets/touch/knobs/knob.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "knob.h"
+
+#include <QBrush>
+#include <QTouchEvent>
+
+Knob::Knob()
+ : QGraphicsEllipseItem(-50, -50, 100, 100)
+{
+ setAcceptTouchEvents(true);
+ setBrush(Qt::lightGray);
+
+ QGraphicsEllipseItem *leftItem = new QGraphicsEllipseItem(0, 0, 20, 20, this);
+ leftItem->setPos(-40, -10);
+ leftItem->setBrush(Qt::darkGreen);
+
+ QGraphicsEllipseItem *rightItem = new QGraphicsEllipseItem(0, 0, 20, 20, this);
+ rightItem->setPos(20, -10);
+ rightItem->setBrush(Qt::darkRed);
+}
+
+bool Knob::sceneEvent(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ {
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
+
+ if (touchEvent->touchPoints().count() == 2) {
+ const QTouchEvent::TouchPoint &touchPoint1 = touchEvent->touchPoints().first();
+ const QTouchEvent::TouchPoint &touchPoint2 = touchEvent->touchPoints().last();
+
+ QLineF line1(touchPoint1.lastScenePos(), touchPoint2.lastScenePos());
+ QLineF line2(touchPoint1.scenePos(), touchPoint2.scenePos());
+
+ setTransform(QTransform().rotate(line2.angleTo(line1)), true);
+ }
+
+ break;
+ }
+
+ default:
+ return QGraphicsItem::sceneEvent(event);
+ }
+
+ return true;
+}
diff --git a/examples/widgets/touch/knobs/knob.h b/examples/widgets/touch/knobs/knob.h
new file mode 100644
index 0000000000..c16b61d6f1
--- /dev/null
+++ b/examples/widgets/touch/knobs/knob.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef KNOB_H
+#define KNOB_H
+
+#include <QGraphicsItem>
+
+class Knob : public QGraphicsEllipseItem
+{
+public:
+ Knob();
+
+ bool sceneEvent(QEvent *event) override;
+};
+
+#endif // KNOB_H
diff --git a/examples/widgets/touch/knobs/knobs.pro b/examples/widgets/touch/knobs/knobs.pro
new file mode 100644
index 0000000000..0915b0665a
--- /dev/null
+++ b/examples/widgets/touch/knobs/knobs.pro
@@ -0,0 +1,8 @@
+QT += widgets
+
+HEADERS = knob.h
+SOURCES = main.cpp knob.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/knobs
+INSTALLS += target
diff --git a/examples/widgets/touch/knobs/main.cpp b/examples/widgets/touch/knobs/main.cpp
new file mode 100644
index 0000000000..ea0e857e7b
--- /dev/null
+++ b/examples/widgets/touch/knobs/main.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QGraphicsView>
+
+#include "knob.h"
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+
+ Knob *knob1 = new Knob;
+ knob1->setPos(-110, 0);
+ Knob *knob2 = new Knob;
+
+ scene.addItem(knob1);
+ scene.addItem(knob2);
+
+ view.showMaximized();
+ view.fitInView(scene.sceneRect().adjusted(-20, -20, 20, 20), Qt::KeepAspectRatio);
+
+ return app.exec();
+}
diff --git a/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png b/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png
new file mode 100644
index 0000000000..7db51fbf55
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/doc/images/pinch-zoom-example.png
Binary files differ
diff --git a/examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc b/examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc
new file mode 100644
index 0000000000..61db2f96c5
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/doc/src/pinchzoom.qdoc
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** 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. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example touch/pinchzoom
+ \title Pinch Zoom Example
+ \ingroup touchinputexamples
+ \brief Shows how to recognize a gesture.
+
+ The Pinch Zoom example shows how to use low-level touch information
+ to recognize a gesture.
+
+ \image touch-pinchzoom-example.png
+*/
diff --git a/examples/widgets/touch/pinchzoom/graphicsview.cpp b/examples/widgets/touch/pinchzoom/graphicsview.cpp
new file mode 100644
index 0000000000..54e134aea2
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/graphicsview.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "graphicsview.h"
+
+#include <QScrollBar>
+#include <QTouchEvent>
+
+GraphicsView::GraphicsView(QGraphicsScene *scene, QWidget *parent)
+ : QGraphicsView(scene, parent), totalScaleFactor(1)
+{
+ viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
+ setDragMode(ScrollHandDrag);
+}
+
+bool GraphicsView::viewportEvent(QEvent *event)
+{
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ {
+ QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);
+ QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();
+ if (touchPoints.count() == 2) {
+ // determine scale factor
+ const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();
+ const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();
+ qreal currentScaleFactor =
+ QLineF(touchPoint0.pos(), touchPoint1.pos()).length()
+ / QLineF(touchPoint0.startPos(), touchPoint1.startPos()).length();
+ if (touchEvent->touchPointStates() & Qt::TouchPointReleased) {
+ // if one of the fingers is released, remember the current scale
+ // factor so that adding another finger later will continue zooming
+ // by adding new scale factor to the existing remembered value.
+ totalScaleFactor *= currentScaleFactor;
+ currentScaleFactor = 1;
+ }
+ setTransform(QTransform().scale(totalScaleFactor * currentScaleFactor,
+ totalScaleFactor * currentScaleFactor));
+ }
+ return true;
+ }
+ default:
+ break;
+ }
+ return QGraphicsView::viewportEvent(event);
+}
diff --git a/examples/widgets/touch/pinchzoom/graphicsview.h b/examples/widgets/touch/pinchzoom/graphicsview.h
new file mode 100644
index 0000000000..d4e2e32d36
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/graphicsview.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#pragma once
+#include <QGraphicsView>
+
+class GraphicsView : public QGraphicsView
+{
+ Q_OBJECT
+
+public:
+ GraphicsView(QGraphicsScene *scene = 0, QWidget *parent = 0);
+
+ bool viewportEvent(QEvent *event) override;
+
+private:
+ qreal totalScaleFactor;
+};
diff --git a/examples/widgets/touch/pinchzoom/images/cheese.jpg b/examples/widgets/touch/pinchzoom/images/cheese.jpg
new file mode 100644
index 0000000000..dea5795fd0
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/images/cheese.jpg
Binary files differ
diff --git a/examples/widgets/touch/pinchzoom/main.cpp b/examples/widgets/touch/pinchzoom/main.cpp
new file mode 100644
index 0000000000..938432600f
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/main.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "graphicsview.h"
+#include "mouse.h"
+
+#include <QtWidgets>
+
+#include <math.h>
+
+static const int MouseCount = 7;
+
+//! [0]
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+//! [0]
+
+//! [1]
+ QGraphicsScene scene;
+ scene.setSceneRect(-300, -300, 600, 600);
+//! [1] //! [2]
+ scene.setItemIndexMethod(QGraphicsScene::NoIndex);
+//! [2]
+
+//! [3]
+ for (int i = 0; i < MouseCount; ++i) {
+ Mouse *mouse = new Mouse;
+ mouse->setPos(::sin((i * 6.28) / MouseCount) * 200,
+ ::cos((i * 6.28) / MouseCount) * 200);
+ scene.addItem(mouse);
+ }
+//! [3]
+
+//! [4]
+ GraphicsView view(&scene);
+ view.setRenderHint(QPainter::Antialiasing);
+ view.setBackgroundBrush(QPixmap(":/images/cheese.jpg"));
+//! [4] //! [5]
+ view.setCacheMode(QGraphicsView::CacheBackground);
+ view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
+//! [5] //! [6]
+ view.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice"));
+ view.showMaximized();
+
+ return app.exec();
+}
+//! [6]
diff --git a/examples/widgets/touch/pinchzoom/mice.qrc b/examples/widgets/touch/pinchzoom/mice.qrc
new file mode 100644
index 0000000000..accdb4d0a6
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/mice.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>images/cheese.jpg</file>
+ </qresource>
+</RCC>
diff --git a/examples/widgets/touch/pinchzoom/mouse.cpp b/examples/widgets/touch/pinchzoom/mouse.cpp
new file mode 100644
index 0000000000..1e6814be13
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/mouse.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mouse.h"
+
+#include <QGraphicsScene>
+#include <QPainter>
+#include <QRandomGenerator>
+#include <QStyleOption>
+#include <qmath.h>
+
+const qreal Pi = M_PI;
+const qreal TwoPi = 2 * M_PI;
+
+static qreal normalizeAngle(qreal angle)
+{
+ while (angle < 0)
+ angle += TwoPi;
+ while (angle > TwoPi)
+ angle -= TwoPi;
+ return angle;
+}
+
+//! [0]
+Mouse::Mouse()
+ : angle(0), speed(0), mouseEyeDirection(0),
+ color(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256))
+{
+ setTransform(QTransform().rotate(QRandomGenerator::global()->bounded(360 * 16)), true);
+ startTimer(1000 / 33);
+}
+//! [0]
+
+//! [1]
+QRectF Mouse::boundingRect() const
+{
+ qreal adjust = 0.5;
+ return QRectF(-18 - adjust, -22 - adjust,
+ 36 + adjust, 60 + adjust);
+}
+//! [1]
+
+//! [2]
+QPainterPath Mouse::shape() const
+{
+ QPainterPath path;
+ path.addRect(-10, -20, 20, 40);
+ return path;
+}
+//! [2]
+
+//! [3]
+void Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
+{
+ // Body
+ painter->setBrush(color);
+ painter->drawEllipse(-10, -20, 20, 40);
+
+ // Eyes
+ painter->setBrush(Qt::white);
+ painter->drawEllipse(-10, -17, 8, 8);
+ painter->drawEllipse(2, -17, 8, 8);
+
+ // Nose
+ painter->setBrush(Qt::black);
+ painter->drawEllipse(QRectF(-2, -22, 4, 4));
+
+ // Pupils
+ painter->drawEllipse(QRectF(-8.0 + mouseEyeDirection, -17, 4, 4));
+ painter->drawEllipse(QRectF(4.0 + mouseEyeDirection, -17, 4, 4));
+
+ // Ears
+ painter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::darkYellow : Qt::red);
+ painter->drawEllipse(-17, -12, 16, 16);
+ painter->drawEllipse(1, -12, 16, 16);
+
+ // Tail
+ QPainterPath path(QPointF(0, 20));
+ path.cubicTo(-5, 22, -5, 22, 0, 25);
+ path.cubicTo(5, 27, 5, 32, 0, 30);
+ path.cubicTo(-5, 32, -5, 42, 0, 35);
+ painter->setBrush(Qt::NoBrush);
+ painter->drawPath(path);
+}
+//! [3]
+
+//! [4]
+void Mouse::timerEvent(QTimerEvent *)
+{
+//! [4]
+ // Don't move too far away
+//! [5]
+ QLineF lineToCenter(QPointF(0, 0), mapFromScene(0, 0));
+ if (lineToCenter.length() > 150) {
+ qreal angleToCenter = std::atan2(lineToCenter.dy(), lineToCenter.dx());
+ angleToCenter = normalizeAngle((Pi - angleToCenter) + Pi / 2);
+
+ if (angleToCenter < Pi && angleToCenter > Pi / 4) {
+ // Rotate left
+ angle += (angle < -Pi / 2) ? 0.25 : -0.25;
+ } else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) {
+ // Rotate right
+ angle += (angle < Pi / 2) ? 0.25 : -0.25;
+ }
+ } else if (::sin(angle) < 0) {
+ angle += 0.25;
+ } else if (::sin(angle) > 0) {
+ angle -= 0.25;
+//! [5] //! [6]
+ }
+//! [6]
+
+ // Try not to crash with any other mice
+//! [7]
+ QList<QGraphicsItem *> dangerMice = scene()->items(QPolygonF()
+ << mapToScene(0, 0)
+ << mapToScene(-30, -50)
+ << mapToScene(30, -50));
+ foreach (QGraphicsItem *item, dangerMice) {
+ if (item == this)
+ continue;
+
+ QLineF lineToMouse(QPointF(0, 0), mapFromItem(item, 0, 0));
+ qreal angleToMouse = std::atan2(lineToMouse.dy(), lineToMouse.dx());
+ angleToMouse = normalizeAngle((Pi - angleToMouse) + Pi / 2);
+
+ if (angleToMouse >= 0 && angleToMouse < Pi / 2) {
+ // Rotate right
+ angle += 0.5;
+ } else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) {
+ // Rotate left
+ angle -= 0.5;
+//! [7] //! [8]
+ }
+//! [8] //! [9]
+ }
+//! [9]
+
+ // Add some random movement
+//! [10]
+ if (dangerMice.size() > 1 && QRandomGenerator::global()->bounded(10) == 0) {
+ if (QRandomGenerator::global()->bounded(1))
+ angle += QRandomGenerator::global()->bounded(1 / 500.0);
+ else
+ angle -= QRandomGenerator::global()->bounded(1 / 500.0);
+ }
+//! [10]
+
+//! [11]
+ speed += (-50 + QRandomGenerator::global()->bounded(100)) / 100.0;
+
+ qreal dx = ::sin(angle) * 10;
+ mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5;
+
+ setTransform(QTransform().rotate(dx), true);
+ setPos(mapToParent(0, -(3 + sin(speed) * 3)));
+}
+//! [11]
diff --git a/examples/widgets/touch/pinchzoom/mouse.h b/examples/widgets/touch/pinchzoom/mouse.h
new file mode 100644
index 0000000000..870bfcd6c0
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/mouse.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MOUSE_H
+#define MOUSE_H
+
+#include <QGraphicsObject>
+
+//! [0]
+class Mouse : public QGraphicsObject
+{
+ Q_OBJECT
+
+public:
+ Mouse();
+
+ QRectF boundingRect() const override;
+ QPainterPath shape() const override;
+ void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
+ QWidget *widget) override;
+
+protected:
+ void timerEvent(QTimerEvent *event) override;
+
+private:
+ qreal angle;
+ qreal speed;
+ qreal mouseEyeDirection;
+ QColor color;
+};
+//! [0]
+
+#endif
diff --git a/examples/widgets/touch/pinchzoom/pinchzoom.pro b/examples/widgets/touch/pinchzoom/pinchzoom.pro
new file mode 100644
index 0000000000..ebbc7ddf1f
--- /dev/null
+++ b/examples/widgets/touch/pinchzoom/pinchzoom.pro
@@ -0,0 +1,16 @@
+QT += widgets
+
+HEADERS += \
+ mouse.h \
+ graphicsview.h
+SOURCES += \
+ main.cpp \
+ mouse.cpp \
+ graphicsview.cpp
+
+RESOURCES += \
+ mice.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/touch/pinchzoom
+INSTALLS += target
diff --git a/examples/widgets/touch/touch.pro b/examples/widgets/touch/touch.pro
new file mode 100644
index 0000000000..018ec134eb
--- /dev/null
+++ b/examples/widgets/touch/touch.pro
@@ -0,0 +1,4 @@
+requires(qtHaveModule(widgets))
+
+TEMPLATE = subdirs
+SUBDIRS = pinchzoom fingerpaint knobs dials
diff --git a/examples/widgets/widgets.pro b/examples/widgets/widgets.pro
index 7e52125125..d975ea8307 100644
--- a/examples/widgets/widgets.pro
+++ b/examples/widgets/widgets.pro
@@ -19,6 +19,7 @@ SUBDIRS = \
scroller \
statemachine \
tools \
+ touch \
tutorials \
widgets
diff --git a/examples/widgets/widgets/tablet/mainwindow.cpp b/examples/widgets/widgets/tablet/mainwindow.cpp
index 994666d4de..a048119533 100644
--- a/examples/widgets/widgets/tablet/mainwindow.cpp
+++ b/examples/widgets/widgets/tablet/mainwindow.cpp
@@ -104,15 +104,16 @@ void MainWindow::setEventCompression(bool compress)
}
//! [5]
-void MainWindow::save()
+bool MainWindow::save()
{
QString path = QDir::currentPath() + "/untitled.png";
QString fileName = QFileDialog::getSaveFileName(this, tr("Save Picture"),
path);
-
- if (!m_canvas->saveImage(fileName))
+ bool success = m_canvas->saveImage(fileName);
+ if (!success)
QMessageBox::information(this, "Error Saving Picture",
"Could not save the image");
+ return success;
}
//! [5]
@@ -128,6 +129,14 @@ void MainWindow::load()
}
//! [6]
+void MainWindow::clear()
+{
+ if (QMessageBox::question(this, tr("Save changes"), tr("Do you want to save your changes?"),
+ QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
+ QMessageBox::Save) != QMessageBox::Save || save())
+ m_canvas->clear();
+}
+
//! [7]
void MainWindow::about()
{
@@ -142,6 +151,7 @@ void MainWindow::createMenus()
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(tr("&Open..."), this, &MainWindow::load, QKeySequence::Open);
fileMenu->addAction(tr("&Save As..."), this, &MainWindow::save, QKeySequence::SaveAs);
+ fileMenu->addAction(tr("&New"), this, &MainWindow::clear, QKeySequence::New);
fileMenu->addAction(tr("E&xit"), this, &MainWindow::close, QKeySequence::Quit);
QMenu *brushMenu = menuBar()->addMenu(tr("&Brush"));
diff --git a/examples/widgets/widgets/tablet/mainwindow.h b/examples/widgets/widgets/tablet/mainwindow.h
index 4b99324f04..4be28784b5 100644
--- a/examples/widgets/widgets/tablet/mainwindow.h
+++ b/examples/widgets/widgets/tablet/mainwindow.h
@@ -72,8 +72,9 @@ private slots:
void setLineWidthValuator(QAction *action);
void setSaturationValuator(QAction *action);
void setEventCompression(bool compress);
- void save();
+ bool save();
void load();
+ void clear();
void about();
private:
diff --git a/examples/widgets/widgets/tablet/tablet.pro b/examples/widgets/widgets/tablet/tablet.pro
index 5772cd0385..647dc2c2f7 100644
--- a/examples/widgets/widgets/tablet/tablet.pro
+++ b/examples/widgets/widgets/tablet/tablet.pro
@@ -10,6 +10,11 @@ SOURCES = mainwindow.cpp \
tabletapplication.cpp
RESOURCES += images.qrc
+# Avoid naming the target "tablet", as it would create an executable
+# named "tablet.exe" on Windows and trigger a bug (in the Wacom drivers, apparently)
+# preventing tablet messages from being received.
+TARGET = qttablet
+
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/tablet
INSTALLS += target
diff --git a/examples/widgets/widgets/tablet/tabletcanvas.cpp b/examples/widgets/widgets/tablet/tabletcanvas.cpp
index 73678ab754..bfcc84e182 100644
--- a/examples/widgets/widgets/tablet/tabletcanvas.cpp
+++ b/examples/widgets/widgets/tablet/tabletcanvas.cpp
@@ -90,6 +90,12 @@ bool TabletCanvas::loadImage(const QString &file)
}
//! [2]
+void TabletCanvas::clear()
+{
+ m_pixmap.fill(Qt::white);
+ update();
+}
+
//! [3]
void TabletCanvas::tabletEvent(QTabletEvent *event)
{
@@ -142,12 +148,14 @@ void TabletCanvas::initPixmap()
m_pixmap = newPixmap;
}
-void TabletCanvas::paintEvent(QPaintEvent *)
+void TabletCanvas::paintEvent(QPaintEvent *event)
{
if (m_pixmap.isNull())
initPixmap();
QPainter painter(this);
- painter.drawPixmap(0, 0, m_pixmap);
+ QRect pixmapPortion = QRect(event->rect().topLeft() * devicePixelRatioF(),
+ event->rect().size() * devicePixelRatioF());
+ painter.drawPixmap(event->rect().topLeft(), m_pixmap, pixmapPortion);
}
//! [4]
diff --git a/examples/widgets/widgets/tablet/tabletcanvas.h b/examples/widgets/widgets/tablet/tabletcanvas.h
index 671d5376f8..c63ef76893 100644
--- a/examples/widgets/widgets/tablet/tabletcanvas.h
+++ b/examples/widgets/widgets/tablet/tabletcanvas.h
@@ -79,6 +79,7 @@ public:
bool saveImage(const QString &file);
bool loadImage(const QString &file);
+ void clear();
void setAlphaChannelValuator(Valuator type)
{ m_alphaChannelValuator = type; }
void setColorSaturationValuator(Valuator type)