summaryrefslogtreecommitdiffstats
path: root/tests/manual/examples/widgets/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'tests/manual/examples/widgets/widgets')
-rw-r--r--tests/manual/examples/widgets/widgets/charactermap/CMakeLists.txt38
-rw-r--r--tests/manual/examples/widgets/widgets/charactermap/charactermap.pro12
-rw-r--r--tests/manual/examples/widgets/widgets/charactermap/characterwidget.cpp145
-rw-r--r--tests/manual/examples/widgets/widgets/charactermap/characterwidget.h50
-rw-r--r--tests/manual/examples/widgets/widgets/charactermap/main.cpp14
-rw-r--r--tests/manual/examples/widgets/widgets/charactermap/mainwindow.cpp264
-rw-r--r--tests/manual/examples/widgets/widgets/charactermap/mainwindow.h50
-rw-r--r--tests/manual/examples/widgets/widgets/digitalclock/CMakeLists.txt37
-rw-r--r--tests/manual/examples/widgets/widgets/digitalclock/digitalclock.cpp36
-rw-r--r--tests/manual/examples/widgets/widgets/digitalclock/digitalclock.h22
-rw-r--r--tests/manual/examples/widgets/widgets/digitalclock/digitalclock.pro9
-rw-r--r--tests/manual/examples/widgets/widgets/digitalclock/main.cpp14
-rw-r--r--tests/manual/examples/widgets/widgets/icons/CMakeLists.txt44
-rw-r--r--tests/manual/examples/widgets/widgets/icons/iconpreviewarea.cpp130
-rw-r--r--tests/manual/examples/widgets/widgets/icons/iconpreviewarea.h47
-rw-r--r--tests/manual/examples/widgets/widgets/icons/icons.pro20
-rw-r--r--tests/manual/examples/widgets/widgets/icons/iconsizespinbox.cpp33
-rw-r--r--tests/manual/examples/widgets/widgets/icons/iconsizespinbox.h22
-rw-r--r--tests/manual/examples/widgets/widgets/icons/imagedelegate.cpp64
-rw-r--r--tests/manual/examples/widgets/widgets/icons/imagedelegate.h31
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/designer.pngbin0 -> 3604 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/find_disabled.pngbin0 -> 501 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/find_normal.pngbin0 -> 838 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/monkey_off_128x128.pngbin0 -> 7045 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/monkey_off_16x16.pngbin0 -> 683 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/monkey_off_32x32.pngbin0 -> 1609 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/monkey_off_64x64.pngbin0 -> 3533 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/monkey_on_128x128.pngbin0 -> 6909 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/monkey_on_16x16.pngbin0 -> 681 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/monkey_on_32x32.pngbin0 -> 1577 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/monkey_on_64x64.pngbin0 -> 3479 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/qt_extended_16x16.pngbin0 -> 1263 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/qt_extended_32x32.pngbin0 -> 15518 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/images/qt_extended_48x48.pngbin0 -> 789 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/icons/main.cpp34
-rw-r--r--tests/manual/examples/widgets/widgets/icons/mainwindow.cpp478
-rw-r--r--tests/manual/examples/widgets/widgets/icons/mainwindow.h74
-rw-r--r--tests/manual/examples/widgets/widgets/imageviewer/CMakeLists.txt44
-rw-r--r--tests/manual/examples/widgets/widgets/imageviewer/imageviewer.cpp364
-rw-r--r--tests/manual/examples/widgets/widgets/imageviewer/imageviewer.h74
-rw-r--r--tests/manual/examples/widgets/widgets/imageviewer/imageviewer.pro11
-rw-r--r--tests/manual/examples/widgets/widgets/imageviewer/main.cpp24
-rw-r--r--tests/manual/examples/widgets/widgets/movie/CMakeLists.txt37
-rw-r--r--tests/manual/examples/widgets/widgets/movie/animation.gifbin0 -> 42629 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/movie/main.cpp15
-rw-r--r--tests/manual/examples/widgets/widgets/movie/movie.pro12
-rw-r--r--tests/manual/examples/widgets/widgets/movie/movieplayer.cpp180
-rw-r--r--tests/manual/examples/widgets/widgets/movie/movieplayer.h59
-rw-r--r--tests/manual/examples/widgets/widgets/styles/CMakeLists.txt51
-rw-r--r--tests/manual/examples/widgets/widgets/styles/images/woodbackground.pngbin0 -> 7691 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/styles/images/woodbutton.pngbin0 -> 7689 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/styles/main.cpp17
-rw-r--r--tests/manual/examples/widgets/widgets/styles/norwegianwoodstyle.cpp310
-rw-r--r--tests/manual/examples/widgets/widgets/styles/norwegianwoodstyle.h43
-rw-r--r--tests/manual/examples/widgets/widgets/styles/styles.pro13
-rw-r--r--tests/manual/examples/widgets/widgets/styles/styles.qrc6
-rw-r--r--tests/manual/examples/widgets/widgets/styles/widgetgallery.cpp277
-rw-r--r--tests/manual/examples/widgets/widgets/styles/widgetgallery.h86
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/CMakeLists.txt84
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked.pngbin0 -> 263 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked_hover.pngbin0 -> 266 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked_pressed.pngbin0 -> 425 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked.pngbin0 -> 159 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked_hover.pngbin0 -> 159 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked_pressed.pngbin0 -> 320 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/down_arrow.pngbin0 -> 175 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/down_arrow_disabled.pngbin0 -> 174 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/frame.pngbin0 -> 253 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/pagefold.pngbin0 -> 1545 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton.pngbin0 -> 533 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton_hover.pngbin0 -> 525 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton_pressed.pngbin0 -> 513 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked.pngbin0 -> 355 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked_hover.pngbin0 -> 532 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked_pressed.pngbin0 -> 599 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked.pngbin0 -> 240 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked_hover.pngbin0 -> 492 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked_pressed.pngbin0 -> 556 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/sizegrip.pngbin0 -> 129 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/spindown.pngbin0 -> 276 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/spindown_hover.pngbin0 -> 268 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/spindown_off.pngbin0 -> 249 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/spindown_pressed.pngbin0 -> 264 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/spinup.pngbin0 -> 283 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/spinup_hover.pngbin0 -> 277 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/spinup_off.pngbin0 -> 274 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/spinup_pressed.pngbin0 -> 277 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/up_arrow.pngbin0 -> 197 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/images/up_arrow_disabled.pngbin0 -> 172 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/layouts/default.ui329
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/layouts/pagefold.ui349
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/main.cpp14
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/mainwindow.cpp41
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/mainwindow.h29
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/mainwindow.ui356
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/qss/coffee.qss117
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/qss/default.qss1
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/qss/pagefold.qss299
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/stylesheet.pro15
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/stylesheet.qrc39
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.cpp64
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.h30
-rw-r--r--tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.ui171
-rw-r--r--tests/manual/examples/widgets/widgets/tetrix/CMakeLists.txt39
-rw-r--r--tests/manual/examples/widgets/widgets/tetrix/main.cpp14
-rw-r--r--tests/manual/examples/widgets/widgets/tetrix/tetrix.pro13
-rw-r--r--tests/manual/examples/widgets/widgets/tetrix/tetrixboard.cpp371
-rw-r--r--tests/manual/examples/widgets/widgets/tetrix/tetrixboard.h79
-rw-r--r--tests/manual/examples/widgets/widgets/tetrix/tetrixpiece.cpp106
-rw-r--r--tests/manual/examples/widgets/widgets/tetrix/tetrixpiece.h38
-rw-r--r--tests/manual/examples/widgets/widgets/tetrix/tetrixwindow.cpp82
-rw-r--r--tests/manual/examples/widgets/widgets/tetrix/tetrixwindow.h38
-rw-r--r--tests/manual/examples/widgets/widgets/validators/CMakeLists.txt55
-rw-r--r--tests/manual/examples/widgets/widgets/validators/ledoff.pngbin0 -> 562 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/validators/ledon.pngbin0 -> 486 bytes
-rw-r--r--tests/manual/examples/widgets/widgets/validators/ledwidget.cpp25
-rw-r--r--tests/manual/examples/widgets/widgets/validators/ledwidget.h27
-rw-r--r--tests/manual/examples/widgets/widgets/validators/localeselector.cpp48
-rw-r--r--tests/manual/examples/widgets/widgets/validators/localeselector.h23
-rw-r--r--tests/manual/examples/widgets/widgets/validators/main.cpp16
-rw-r--r--tests/manual/examples/widgets/widgets/validators/validators.pro12
-rw-r--r--tests/manual/examples/widgets/widgets/validators/validators.qrc6
-rw-r--r--tests/manual/examples/widgets/widgets/validators/validators.ui468
-rw-r--r--tests/manual/examples/widgets/widgets/validators/validatorwidget.cpp75
-rw-r--r--tests/manual/examples/widgets/widgets/validators/validatorwidget.h22
125 files changed, 6786 insertions, 0 deletions
diff --git a/tests/manual/examples/widgets/widgets/charactermap/CMakeLists.txt b/tests/manual/examples/widgets/widgets/charactermap/CMakeLists.txt
new file mode 100644
index 0000000000..f02ac52689
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/charactermap/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(charactermap LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/charactermap")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+
+qt_standard_project_setup()
+
+qt_add_executable(charactermap
+ characterwidget.cpp characterwidget.h
+ main.cpp
+ mainwindow.cpp mainwindow.h
+)
+
+set_target_properties(charactermap PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(charactermap PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+)
+
+install(TARGETS charactermap
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/tests/manual/examples/widgets/widgets/charactermap/charactermap.pro b/tests/manual/examples/widgets/widgets/charactermap/charactermap.pro
new file mode 100644
index 0000000000..373aabca73
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/charactermap/charactermap.pro
@@ -0,0 +1,12 @@
+QT += widgets
+requires(qtConfig(combobox))
+
+HEADERS = characterwidget.h \
+ mainwindow.h
+SOURCES = characterwidget.cpp \
+ mainwindow.cpp \
+ main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/charactermap
+INSTALLS += target
diff --git a/tests/manual/examples/widgets/widgets/charactermap/characterwidget.cpp b/tests/manual/examples/widgets/widgets/charactermap/characterwidget.cpp
new file mode 100644
index 0000000000..6287a44e80
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/charactermap/characterwidget.cpp
@@ -0,0 +1,145 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "characterwidget.h"
+
+#include <QFontDatabase>
+#include <QMouseEvent>
+#include <QPainter>
+#include <QToolTip>
+
+//! [0]
+CharacterWidget::CharacterWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ calculateSquareSize();
+ setMouseTracking(true);
+}
+//! [0]
+
+//! [1]
+void CharacterWidget::updateFont(const QFont &font)
+{
+ displayFont.setFamily(font.family());
+ calculateSquareSize();
+ adjustSize();
+ update();
+}
+//! [1]
+
+//! [2]
+void CharacterWidget::updateSize(const QString &fontSize)
+{
+ displayFont.setPointSize(fontSize.toInt());
+ calculateSquareSize();
+ adjustSize();
+ update();
+}
+//! [2]
+
+void CharacterWidget::updateStyle(const QString &fontStyle)
+{
+ const QFont::StyleStrategy oldStrategy = displayFont.styleStrategy();
+ displayFont = QFontDatabase::font(displayFont.family(), fontStyle, displayFont.pointSize());
+ displayFont.setStyleStrategy(oldStrategy);
+ calculateSquareSize();
+ adjustSize();
+ update();
+}
+
+void CharacterWidget::updateFontMerging(bool enable)
+{
+ if (enable)
+ displayFont.setStyleStrategy(QFont::PreferDefault);
+ else
+ displayFont.setStyleStrategy(QFont::NoFontMerging);
+ adjustSize();
+ update();
+}
+
+void CharacterWidget::calculateSquareSize()
+{
+ squareSize = qMax(16, 4 + QFontMetrics(displayFont, this).height());
+}
+
+//! [3]
+QSize CharacterWidget::sizeHint() const
+{
+ return QSize(columns*squareSize, (65536 / columns) * squareSize);
+}
+//! [3]
+
+//! [4]
+void CharacterWidget::mouseMoveEvent(QMouseEvent *event)
+{
+ QPoint widgetPosition = mapFromGlobal(event->globalPosition().toPoint());
+ uint key = (widgetPosition.y() / squareSize) * columns + widgetPosition.x() / squareSize;
+
+ QString text = QString::fromLatin1("<p>Character: <span style=\"font-size: 24pt; font-family: %1\">").arg(displayFont.family())
+ + QChar(key)
+ + QString::fromLatin1("</span><p>Value: 0x")
+ + QString::number(key, 16);
+ QToolTip::showText(event->globalPosition().toPoint(), text, this);
+}
+//! [4]
+
+//! [5]
+void CharacterWidget::mousePressEvent(QMouseEvent *event)
+{
+ if (event->button() == Qt::LeftButton) {
+ lastKey = (event->position().toPoint().y() / squareSize) * columns + event->position().toPoint().x() / squareSize;
+ if (QChar(lastKey).category() != QChar::Other_NotAssigned)
+ emit characterSelected(QString(QChar(lastKey)));
+ update();
+ }
+ else
+ QWidget::mousePressEvent(event);
+}
+//! [5]
+
+//! [6]
+void CharacterWidget::paintEvent(QPaintEvent *event)
+{
+ QPainter painter(this);
+ painter.fillRect(event->rect(), QBrush(Qt::white));
+ painter.setFont(displayFont);
+//! [6]
+
+//! [7]
+ QRect redrawRect = event->rect();
+ int beginRow = redrawRect.top() / squareSize;
+ int endRow = redrawRect.bottom() / squareSize;
+ int beginColumn = redrawRect.left() / squareSize;
+ int endColumn = redrawRect.right() / squareSize;
+//! [7]
+
+//! [8]
+ painter.setPen(QPen(Qt::gray));
+ for (int row = beginRow; row <= endRow; ++row) {
+ for (int column = beginColumn; column <= endColumn; ++column) {
+ painter.drawRect(column * squareSize, row * squareSize, squareSize, squareSize);
+ }
+//! [8] //! [9]
+ }
+//! [9]
+
+//! [10]
+ QFontMetrics fontMetrics(displayFont);
+ painter.setPen(QPen(Qt::black));
+ for (int row = beginRow; row <= endRow; ++row) {
+ for (int column = beginColumn; column <= endColumn; ++column) {
+ int key = row * columns + column;
+ painter.setClipRect(column * squareSize, row * squareSize, squareSize, squareSize);
+
+ if (key == lastKey)
+ painter.fillRect(column * squareSize + 1, row * squareSize + 1,
+ squareSize, squareSize, QBrush(Qt::red));
+
+ painter.drawText(column * squareSize + (squareSize / 2) -
+ fontMetrics.horizontalAdvance(QChar(key)) / 2,
+ row * squareSize + 4 + fontMetrics.ascent(),
+ QString(QChar(key)));
+ }
+ }
+}
+//! [10]
diff --git a/tests/manual/examples/widgets/widgets/charactermap/characterwidget.h b/tests/manual/examples/widgets/widgets/charactermap/characterwidget.h
new file mode 100644
index 0000000000..b8aa76d111
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/charactermap/characterwidget.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef CHARACTERWIDGET_H
+#define CHARACTERWIDGET_H
+
+#include <QFont>
+#include <QSize>
+#include <QString>
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QMouseEvent;
+class QPaintEvent;
+QT_END_NAMESPACE
+
+//! [0]
+class CharacterWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ CharacterWidget(QWidget *parent = nullptr);
+ QSize sizeHint() const override;
+
+public slots:
+ void updateFont(const QFont &font);
+ void updateSize(const QString &fontSize);
+ void updateStyle(const QString &fontStyle);
+ void updateFontMerging(bool enable);
+
+signals:
+ void characterSelected(const QString &character);
+
+protected:
+ void mouseMoveEvent(QMouseEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void paintEvent(QPaintEvent *event) override;
+
+private:
+ void calculateSquareSize();
+
+ QFont displayFont;
+ int columns = 16;
+ int lastKey = -1;
+ int squareSize = 0;
+};
+//! [0]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/charactermap/main.cpp b/tests/manual/examples/widgets/widgets/charactermap/main.cpp
new file mode 100644
index 0000000000..7d7cf3e573
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/charactermap/main.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ MainWindow window;
+ window.show();
+ return app.exec();
+}
diff --git a/tests/manual/examples/widgets/widgets/charactermap/mainwindow.cpp b/tests/manual/examples/widgets/widgets/charactermap/mainwindow.cpp
new file mode 100644
index 0000000000..fcc00f9642
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/charactermap/mainwindow.cpp
@@ -0,0 +1,264 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "mainwindow.h"
+#include "characterwidget.h"
+
+#include <QApplication>
+#include <QBoxLayout>
+#include <QCheckBox>
+#include <QClipboard>
+#include <QDialog>
+#include <QDialogButtonBox>
+#include <QFontComboBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QMenuBar>
+#include <QPlainTextEdit>
+#include <QPushButton>
+#include <QScreen>
+#include <QScrollArea>
+#include <QStatusBar>
+#include <QTextStream>
+
+//! [0]
+Q_DECLARE_METATYPE(QFontComboBox::FontFilter)
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+{
+ QMenu *fileMenu = menuBar()->addMenu(tr("File"));
+ fileMenu->addAction(tr("Quit"), this, &QWidget::close);
+ QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
+ helpMenu->addAction(tr("Show Font Info"), this, &MainWindow::showInfo);
+ helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
+
+ QWidget *centralWidget = new QWidget;
+
+ QLabel *filterLabel = new QLabel(tr("Filter:"));
+ filterCombo = new QComboBox;
+ filterCombo->addItem(tr("All"), QVariant::fromValue(QFontComboBox::AllFonts));
+ filterCombo->addItem(tr("Scalable"), QVariant::fromValue(QFontComboBox::ScalableFonts));
+ filterCombo->addItem(tr("Monospaced"), QVariant::fromValue(QFontComboBox::MonospacedFonts));
+ filterCombo->addItem(tr("Proportional"), QVariant::fromValue(QFontComboBox::ProportionalFonts));
+ filterCombo->setCurrentIndex(0);
+ connect(filterCombo, &QComboBox::currentIndexChanged,
+ this, &MainWindow::filterChanged);
+
+ QLabel *fontLabel = new QLabel(tr("Font:"));
+ fontCombo = new QFontComboBox;
+ QLabel *sizeLabel = new QLabel(tr("Size:"));
+ sizeCombo = new QComboBox;
+ QLabel *styleLabel = new QLabel(tr("Style:"));
+ styleCombo = new QComboBox;
+ QLabel *fontMergingLabel = new QLabel(tr("Automatic Font Merging:"));
+ fontMerging = new QCheckBox;
+ fontMerging->setChecked(true);
+
+ scrollArea = new QScrollArea;
+ characterWidget = new CharacterWidget;
+ scrollArea->setWidget(characterWidget);
+//! [0]
+
+//! [1]
+ findStyles(fontCombo->currentFont());
+//! [1]
+ findSizes(fontCombo->currentFont());
+
+//! [2]
+ lineEdit = new QLineEdit;
+ lineEdit->setClearButtonEnabled(true);
+#ifndef QT_NO_CLIPBOARD
+ QPushButton *clipboardButton = new QPushButton(tr("&To clipboard"));
+//! [2]
+
+#endif
+
+//! [4]
+ connect(fontCombo, &QFontComboBox::currentFontChanged,
+ this, &MainWindow::findStyles);
+ connect(fontCombo, &QFontComboBox::currentFontChanged,
+ this, &MainWindow::findSizes);
+ connect(fontCombo, &QFontComboBox::currentFontChanged,
+ characterWidget, &CharacterWidget::updateFont);
+ connect(sizeCombo, &QComboBox::currentTextChanged,
+ characterWidget, &CharacterWidget::updateSize);
+ connect(styleCombo, &QComboBox::currentTextChanged,
+ characterWidget, &CharacterWidget::updateStyle);
+//! [4] //! [5]
+ connect(characterWidget, &CharacterWidget::characterSelected,
+ this, &MainWindow::insertCharacter);
+
+#ifndef QT_NO_CLIPBOARD
+ connect(clipboardButton, &QAbstractButton::clicked, this, &MainWindow::updateClipboard);
+#endif
+//! [5]
+ connect(fontMerging, &QAbstractButton::toggled, characterWidget, &CharacterWidget::updateFontMerging);
+
+//! [6]
+ QHBoxLayout *controlsLayout = new QHBoxLayout;
+ controlsLayout->addWidget(filterLabel);
+ controlsLayout->addWidget(filterCombo, 1);
+ controlsLayout->addWidget(fontLabel);
+ controlsLayout->addWidget(fontCombo, 1);
+ controlsLayout->addWidget(sizeLabel);
+ controlsLayout->addWidget(sizeCombo, 1);
+ controlsLayout->addWidget(styleLabel);
+ controlsLayout->addWidget(styleCombo, 1);
+ controlsLayout->addWidget(fontMergingLabel);
+ controlsLayout->addWidget(fontMerging, 1);
+ controlsLayout->addStretch(1);
+
+ QHBoxLayout *lineLayout = new QHBoxLayout;
+ lineLayout->addWidget(lineEdit, 1);
+ lineLayout->addSpacing(12);
+#ifndef QT_NO_CLIPBOARD
+ lineLayout->addWidget(clipboardButton);
+#endif
+
+ QVBoxLayout *centralLayout = new QVBoxLayout;
+ centralLayout->addLayout(controlsLayout);
+ centralLayout->addWidget(scrollArea, 1);
+ centralLayout->addSpacing(4);
+ centralLayout->addLayout(lineLayout);
+ centralWidget->setLayout(centralLayout);
+
+ setCentralWidget(centralWidget);
+ setWindowTitle(tr("Character Map"));
+}
+//! [6]
+
+//! [7]
+void MainWindow::findStyles(const QFont &font)
+{
+ QString currentItem = styleCombo->currentText();
+ styleCombo->clear();
+//! [7]
+
+//! [8]
+ const QStringList styles = QFontDatabase::styles(font.family());
+ for (const QString &style : styles)
+ styleCombo->addItem(style);
+
+ int styleIndex = styleCombo->findText(currentItem);
+
+ if (styleIndex == -1)
+ styleCombo->setCurrentIndex(0);
+ else
+ styleCombo->setCurrentIndex(styleIndex);
+}
+//! [8]
+
+void MainWindow::filterChanged(int f)
+{
+ const QFontComboBox::FontFilter filter =
+ qvariant_cast<QFontComboBox::FontFilter>(filterCombo->itemData(f));
+ fontCombo->setFontFilters(filter);
+ statusBar()->showMessage(tr("%n font(s) found", nullptr, fontCombo->count()));
+}
+
+void MainWindow::findSizes(const QFont &font)
+{
+ QString currentSize = sizeCombo->currentText();
+
+ {
+ const QSignalBlocker blocker(sizeCombo);
+ // sizeCombo signals are now blocked until end of scope
+ sizeCombo->clear();
+
+ if (QFontDatabase::isSmoothlyScalable(font.family(), QFontDatabase::styleString(font))) {
+ const QList<int> sizes = QFontDatabase::standardSizes();
+ for (const int size : sizes) {
+ sizeCombo->addItem(QVariant(size).toString());
+ sizeCombo->setEditable(true);
+ }
+
+ } else {
+ const QList<int> sizes = QFontDatabase::smoothSizes(font.family(), QFontDatabase::styleString(font));
+ for (const int size : sizes ) {
+ sizeCombo->addItem(QVariant(size).toString());
+ sizeCombo->setEditable(false);
+ }
+ }
+ }
+
+ int sizeIndex = sizeCombo->findText(currentSize);
+
+ if(sizeIndex == -1)
+ sizeCombo->setCurrentIndex(qMax(0, sizeCombo->count() / 3));
+ else
+ sizeCombo->setCurrentIndex(sizeIndex);
+}
+
+//! [9]
+void MainWindow::insertCharacter(const QString &character)
+{
+ lineEdit->insert(character);
+}
+//! [9]
+
+//! [10]
+#ifndef QT_NO_CLIPBOARD
+void MainWindow::updateClipboard()
+{
+//! [11]
+ QGuiApplication::clipboard()->setText(lineEdit->text(), QClipboard::Clipboard);
+//! [11]
+ QGuiApplication::clipboard()->setText(lineEdit->text(), QClipboard::Selection);
+}
+#endif
+
+class FontInfoDialog : public QDialog
+{
+public:
+ explicit FontInfoDialog(QWidget *parent = nullptr);
+
+private:
+ QString text() const;
+};
+
+FontInfoDialog::FontInfoDialog(QWidget *parent) : QDialog(parent)
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ QPlainTextEdit *textEdit = new QPlainTextEdit(text(), this);
+ textEdit->setReadOnly(true);
+ textEdit->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
+ mainLayout->addWidget(textEdit);
+ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, this);
+ connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
+ mainLayout->addWidget(buttonBox);
+}
+
+QString FontInfoDialog::text() const
+{
+ QString text;
+ QTextStream str(&text);
+ const QFont defaultFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
+ const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
+ const QFont titleFont = QFontDatabase::systemFont(QFontDatabase::TitleFont);
+ const QFont smallestReadableFont = QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont);
+
+ str << "Qt " << QT_VERSION_STR << " on " << QGuiApplication::platformName()
+ << ", " << logicalDpiX() << "DPI";
+ if (!qFuzzyCompare(devicePixelRatio(), qreal(1)))
+ str << ", device pixel ratio: " << devicePixelRatio();
+ str << "\n\nDefault font : " << defaultFont.family() << ", " << defaultFont.pointSizeF() << "pt\n"
+ << "Fixed font : " << fixedFont.family() << ", " << fixedFont.pointSizeF() << "pt\n"
+ << "Title font : " << titleFont.family() << ", " << titleFont.pointSizeF() << "pt\n"
+ << "Smallest font: " << smallestReadableFont.family() << ", " << smallestReadableFont.pointSizeF() << "pt\n";
+
+ return text;
+}
+
+void MainWindow::showInfo()
+{
+ const QRect screenGeometry = screen()->geometry();
+ FontInfoDialog *dialog = new FontInfoDialog(this);
+ dialog->setWindowTitle(tr("Fonts"));
+ dialog->setAttribute(Qt::WA_DeleteOnClose);
+ dialog->resize(screenGeometry.width() / 4, screenGeometry.height() / 4);
+ dialog->show();
+}
+
+//! [10]
diff --git a/tests/manual/examples/widgets/widgets/charactermap/mainwindow.h b/tests/manual/examples/widgets/widgets/charactermap/mainwindow.h
new file mode 100644
index 0000000000..b8f3c166eb
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/charactermap/mainwindow.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+#include <QString>
+
+QT_BEGIN_NAMESPACE
+class QClipboard;
+class QComboBox;
+class QFontComboBox;
+class QLineEdit;
+class QScrollArea;
+class QCheckBox;
+QT_END_NAMESPACE
+class CharacterWidget;
+
+//! [0]
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = nullptr);
+
+public slots:
+ void filterChanged(int);
+ void findStyles(const QFont &font);
+ void findSizes(const QFont &font);
+ void insertCharacter(const QString &character);
+#ifndef QT_NO_CLIPBOARD
+ void updateClipboard();
+#endif
+ void showInfo();
+
+private:
+ CharacterWidget *characterWidget;
+ QComboBox *filterCombo;
+ QComboBox *styleCombo;
+ QComboBox *sizeCombo;
+ QFontComboBox *fontCombo;
+ QLineEdit *lineEdit;
+ QScrollArea *scrollArea;
+ QCheckBox *fontMerging;
+};
+//! [0]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/digitalclock/CMakeLists.txt b/tests/manual/examples/widgets/widgets/digitalclock/CMakeLists.txt
new file mode 100644
index 0000000000..04d9c53ed3
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/digitalclock/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(digitalclock LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/digitalclock")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+
+qt_standard_project_setup()
+
+qt_add_executable(digitalclock
+ digitalclock.cpp digitalclock.h
+ main.cpp
+)
+
+set_target_properties(digitalclock PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(digitalclock PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+)
+
+install(TARGETS digitalclock
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/tests/manual/examples/widgets/widgets/digitalclock/digitalclock.cpp b/tests/manual/examples/widgets/widgets/digitalclock/digitalclock.cpp
new file mode 100644
index 0000000000..4eec982c25
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/digitalclock/digitalclock.cpp
@@ -0,0 +1,36 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "digitalclock.h"
+
+#include <QTime>
+#include <QTimer>
+
+//! [0]
+DigitalClock::DigitalClock(QWidget *parent)
+ : QLCDNumber(parent)
+{
+ setSegmentStyle(Filled);
+
+ QTimer *timer = new QTimer(this);
+ connect(timer, &QTimer::timeout, this, &DigitalClock::showTime);
+ timer->start(1000);
+
+ showTime();
+
+ setWindowTitle(tr("Digital Clock"));
+ resize(150, 60);
+}
+//! [0]
+
+//! [1]
+void DigitalClock::showTime()
+//! [1] //! [2]
+{
+ QTime time = QTime::currentTime();
+ QString text = time.toString("hh:mm");
+ if ((time.second() % 2) == 0)
+ text[2] = ' ';
+ display(text);
+}
+//! [2]
diff --git a/tests/manual/examples/widgets/widgets/digitalclock/digitalclock.h b/tests/manual/examples/widgets/widgets/digitalclock/digitalclock.h
new file mode 100644
index 0000000000..7b028cb06e
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/digitalclock/digitalclock.h
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef DIGITALCLOCK_H
+#define DIGITALCLOCK_H
+
+#include <QLCDNumber>
+
+//! [0]
+class DigitalClock : public QLCDNumber
+{
+ Q_OBJECT
+
+public:
+ DigitalClock(QWidget *parent = nullptr);
+
+private slots:
+ void showTime();
+};
+//! [0]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/digitalclock/digitalclock.pro b/tests/manual/examples/widgets/widgets/digitalclock/digitalclock.pro
new file mode 100644
index 0000000000..4e4bc0f557
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/digitalclock/digitalclock.pro
@@ -0,0 +1,9 @@
+QT += widgets
+
+HEADERS = digitalclock.h
+SOURCES = digitalclock.cpp \
+ main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/digitalclock
+INSTALLS += target
diff --git a/tests/manual/examples/widgets/widgets/digitalclock/main.cpp b/tests/manual/examples/widgets/widgets/digitalclock/main.cpp
new file mode 100644
index 0000000000..d930e72f23
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/digitalclock/main.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QApplication>
+
+#include "digitalclock.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ DigitalClock clock;
+ clock.show();
+ return app.exec();
+}
diff --git a/tests/manual/examples/widgets/widgets/icons/CMakeLists.txt b/tests/manual/examples/widgets/widgets/icons/CMakeLists.txt
new file mode 100644
index 0000000000..f36e47bef6
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/CMakeLists.txt
@@ -0,0 +1,44 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(icons LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/icons")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+
+qt_standard_project_setup()
+
+qt_add_executable(icons
+ iconpreviewarea.cpp iconpreviewarea.h
+ iconsizespinbox.cpp iconsizespinbox.h
+ imagedelegate.cpp imagedelegate.h
+ main.cpp
+ mainwindow.cpp mainwindow.h
+)
+
+set_target_properties(icons PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_compile_definitions(icons PRIVATE
+ SRCDIR="${CMAKE_CURRENT_SOURCE_DIR}"
+)
+
+target_link_libraries(icons PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+)
+
+install(TARGETS icons
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/tests/manual/examples/widgets/widgets/icons/iconpreviewarea.cpp b/tests/manual/examples/widgets/widgets/icons/iconpreviewarea.cpp
new file mode 100644
index 0000000000..42a5fa7914
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/iconpreviewarea.cpp
@@ -0,0 +1,130 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "iconpreviewarea.h"
+
+#include <QGridLayout>
+#include <QLabel>
+#include <QWindow>
+
+//! [0]
+IconPreviewArea::IconPreviewArea(QWidget *parent)
+ : QWidget(parent)
+{
+ QGridLayout *mainLayout = new QGridLayout(this);
+
+ for (int row = 0; row < NumStates; ++row) {
+ stateLabels[row] = createHeaderLabel(IconPreviewArea::iconStateNames().at(row));
+ mainLayout->addWidget(stateLabels[row], row + 1, 0);
+ }
+ Q_ASSERT(NumStates == 2);
+
+ for (int column = 0; column < NumModes; ++column) {
+ modeLabels[column] = createHeaderLabel(IconPreviewArea::iconModeNames().at(column));
+ mainLayout->addWidget(modeLabels[column], 0, column + 1);
+ }
+ Q_ASSERT(NumModes == 4);
+
+ for (int column = 0; column < NumModes; ++column) {
+ for (int row = 0; row < NumStates; ++row) {
+ pixmapLabels[column][row] = createPixmapLabel();
+ mainLayout->addWidget(pixmapLabels[column][row], row + 1, column + 1);
+ }
+ }
+}
+//! [0]
+
+//! [42]
+QList<QIcon::Mode> IconPreviewArea::iconModes()
+{
+ static const QList<QIcon::Mode> result = { QIcon::Normal, QIcon::Active, QIcon::Disabled,
+ QIcon::Selected };
+ return result;
+}
+
+QList<QIcon::State> IconPreviewArea::iconStates()
+{
+ static const QList<QIcon::State> result = { QIcon::Off, QIcon::On };
+ return result;
+}
+
+QStringList IconPreviewArea::iconModeNames()
+{
+ static const QStringList result = {tr("Normal"), tr("Active"), tr("Disabled"), tr("Selected")};
+ return result;
+}
+
+QStringList IconPreviewArea::iconStateNames()
+{
+ static const QStringList result = {tr("Off"), tr("On")};
+ return result;
+}
+//! [42]
+
+//! [1]
+void IconPreviewArea::setIcon(const QIcon &icon)
+{
+ this->icon = icon;
+ updatePixmapLabels();
+}
+//! [1]
+
+//! [2]
+void IconPreviewArea::setSize(const QSize &size)
+{
+ if (size != this->size) {
+ this->size = size;
+ updatePixmapLabels();
+ }
+}
+//! [2]
+
+//! [3]
+QLabel *IconPreviewArea::createHeaderLabel(const QString &text)
+{
+ QLabel *label = new QLabel(tr("<b>%1</b>").arg(text));
+ label->setAlignment(Qt::AlignCenter);
+ return label;
+}
+//! [3]
+
+//! [4]
+QLabel *IconPreviewArea::createPixmapLabel()
+{
+ QLabel *label = new QLabel;
+ label->setEnabled(false);
+ label->setAlignment(Qt::AlignCenter);
+ label->setFrameShape(QFrame::Box);
+ label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ label->setBackgroundRole(QPalette::Base);
+ label->setAutoFillBackground(true);
+ label->setMinimumSize(132, 132);
+ return label;
+}
+//! [4]
+
+//! [5]
+void IconPreviewArea::updatePixmapLabels()
+{
+ for (int column = 0; column < NumModes; ++column) {
+ for (int row = 0; row < NumStates; ++row) {
+ const QPixmap pixmap =
+ icon.pixmap(size, devicePixelRatio(), IconPreviewArea::iconModes().at(column),
+ IconPreviewArea::iconStates().at(row));
+ QLabel *pixmapLabel = pixmapLabels[column][row];
+ pixmapLabel->setPixmap(pixmap);
+ pixmapLabel->setEnabled(!pixmap.isNull());
+ QString toolTip;
+ if (!pixmap.isNull()) {
+ const QSize actualSize = icon.actualSize(size);
+ toolTip =
+ tr("Size: %1x%2\nActual size: %3x%4\nDevice pixel ratio: %5")
+ .arg(size.width()).arg(size.height())
+ .arg(actualSize.width()).arg(actualSize.height())
+ .arg(pixmap.devicePixelRatio());
+ }
+ pixmapLabel->setToolTip(toolTip);
+ }
+ }
+}
+//! [5]
diff --git a/tests/manual/examples/widgets/widgets/icons/iconpreviewarea.h b/tests/manual/examples/widgets/widgets/icons/iconpreviewarea.h
new file mode 100644
index 0000000000..c59ebc42ba
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/iconpreviewarea.h
@@ -0,0 +1,47 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef ICONPREVIEWAREA_H
+#define ICONPREVIEWAREA_H
+
+#include <QIcon>
+#include <QWidget>
+#include <QStringList>
+#include <QList>
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+QT_END_NAMESPACE
+
+//! [0]
+class IconPreviewArea : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit IconPreviewArea(QWidget *parent = nullptr);
+
+ void setIcon(const QIcon &icon);
+ void setSize(const QSize &size);
+
+ static QList<QIcon::Mode> iconModes();
+ static QList<QIcon::State> iconStates();
+ static QStringList iconModeNames();
+ static QStringList iconStateNames();
+
+private:
+ QLabel *createHeaderLabel(const QString &text);
+ QLabel *createPixmapLabel();
+ void updatePixmapLabels();
+
+ enum { NumModes = 4, NumStates = 2 };
+
+ QIcon icon;
+ QSize size;
+ QLabel *stateLabels[NumStates];
+ QLabel *modeLabels[NumModes];
+ QLabel *pixmapLabels[NumModes][NumStates];
+};
+//! [0]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/icons/icons.pro b/tests/manual/examples/widgets/widgets/icons/icons.pro
new file mode 100644
index 0000000000..243ce6b092
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/icons.pro
@@ -0,0 +1,20 @@
+QT += widgets
+requires(qtConfig(combobox))
+
+HEADERS = iconpreviewarea.h \
+ iconsizespinbox.h \
+ imagedelegate.h \
+ mainwindow.h
+SOURCES = iconpreviewarea.cpp \
+ iconsizespinbox.cpp \
+ imagedelegate.cpp \
+ main.cpp \
+ mainwindow.cpp
+
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
+
+EXAMPLE_FILES = images/*
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/icons
+INSTALLS += target
diff --git a/tests/manual/examples/widgets/widgets/icons/iconsizespinbox.cpp b/tests/manual/examples/widgets/widgets/icons/iconsizespinbox.cpp
new file mode 100644
index 0000000000..16c88f4dd0
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/iconsizespinbox.cpp
@@ -0,0 +1,33 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "iconsizespinbox.h"
+
+#include <QRegularExpression>
+
+//! [0]
+IconSizeSpinBox::IconSizeSpinBox(QWidget *parent)
+ : QSpinBox(parent)
+{
+}
+//! [0]
+
+//! [1]
+int IconSizeSpinBox::valueFromText(const QString &text) const
+{
+ static const QRegularExpression regExp(tr("(\\d+)(\\s*[xx]\\s*\\d+)?"));
+ Q_ASSERT(regExp.isValid());
+
+ const QRegularExpressionMatch match = regExp.match(text);
+ if (match.isValid())
+ return match.captured(1).toInt();
+ return 0;
+}
+//! [1]
+
+//! [2]
+QString IconSizeSpinBox::textFromValue(int value) const
+{
+ return tr("%1 x %1").arg(value);
+}
+//! [2]
diff --git a/tests/manual/examples/widgets/widgets/icons/iconsizespinbox.h b/tests/manual/examples/widgets/widgets/icons/iconsizespinbox.h
new file mode 100644
index 0000000000..ac304b4794
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/iconsizespinbox.h
@@ -0,0 +1,22 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef ICONSIZESPINBOX_H
+#define ICONSIZESPINBOX_H
+
+#include <QSpinBox>
+
+//! [0]
+class IconSizeSpinBox : public QSpinBox
+{
+ Q_OBJECT
+
+public:
+ explicit IconSizeSpinBox(QWidget *parent = nullptr);
+
+ int valueFromText(const QString &text) const override;
+ QString textFromValue(int value) const override;
+};
+//! [0]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/icons/imagedelegate.cpp b/tests/manual/examples/widgets/widgets/icons/imagedelegate.cpp
new file mode 100644
index 0000000000..ec3c227c71
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/imagedelegate.cpp
@@ -0,0 +1,64 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "imagedelegate.h"
+#include "iconpreviewarea.h"
+
+#include <QComboBox>
+
+//! [0]
+ImageDelegate::ImageDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+{}
+//! [0]
+
+//! [1]
+QWidget *ImageDelegate::createEditor(QWidget *parent,
+ const QStyleOptionViewItem & /* option */,
+ const QModelIndex &index) const
+{
+ QComboBox *comboBox = new QComboBox(parent);
+ if (index.column() == 1)
+ comboBox->addItems(IconPreviewArea::iconModeNames());
+ else if (index.column() == 2)
+ comboBox->addItems(IconPreviewArea::iconStateNames());
+
+ connect(comboBox, &QComboBox::activated,
+ this, &ImageDelegate::emitCommitData);
+
+ return comboBox;
+}
+//! [1]
+
+//! [2]
+void ImageDelegate::setEditorData(QWidget *editor,
+ const QModelIndex &index) const
+{
+ QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
+ if (!comboBox)
+ return;
+
+ int pos = comboBox->findText(index.model()->data(index).toString(),
+ Qt::MatchExactly);
+ comboBox->setCurrentIndex(pos);
+}
+//! [2]
+
+//! [3]
+void ImageDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const
+{
+ QComboBox *comboBox = qobject_cast<QComboBox *>(editor);
+ if (!comboBox)
+ return;
+
+ model->setData(index, comboBox->currentText());
+}
+//! [3]
+
+//! [4]
+void ImageDelegate::emitCommitData()
+{
+ emit commitData(qobject_cast<QWidget *>(sender()));
+}
+//! [4]
diff --git a/tests/manual/examples/widgets/widgets/icons/imagedelegate.h b/tests/manual/examples/widgets/widgets/icons/imagedelegate.h
new file mode 100644
index 0000000000..29707e68c6
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/imagedelegate.h
@@ -0,0 +1,31 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef IMAGEDELEGATE_H
+#define IMAGEDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+//! [0]
+class ImageDelegate : public QStyledItemDelegate
+{
+ Q_OBJECT
+
+public:
+ explicit ImageDelegate(QObject *parent = nullptr);
+//! [0]
+
+//! [1]
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const override;
+ void setEditorData(QWidget *editor, const QModelIndex &index) const override;
+ void setModelData(QWidget *editor, QAbstractItemModel *model,
+ const QModelIndex &index) const override;
+
+//! [1] //! [2]
+private slots:
+ void emitCommitData();
+//! [2]
+};
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/icons/images/designer.png b/tests/manual/examples/widgets/widgets/icons/images/designer.png
new file mode 100644
index 0000000000..9f8578b49e
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/designer.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/find_disabled.png b/tests/manual/examples/widgets/widgets/icons/images/find_disabled.png
new file mode 100644
index 0000000000..e85e33fe05
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/find_disabled.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/find_normal.png b/tests/manual/examples/widgets/widgets/icons/images/find_normal.png
new file mode 100644
index 0000000000..728c27f905
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/find_normal.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/monkey_off_128x128.png b/tests/manual/examples/widgets/widgets/icons/images/monkey_off_128x128.png
new file mode 100644
index 0000000000..f878267287
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/monkey_off_128x128.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/monkey_off_16x16.png b/tests/manual/examples/widgets/widgets/icons/images/monkey_off_16x16.png
new file mode 100644
index 0000000000..0ac57d7d4f
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/monkey_off_16x16.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/monkey_off_32x32.png b/tests/manual/examples/widgets/widgets/icons/images/monkey_off_32x32.png
new file mode 100644
index 0000000000..1f7fab694c
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/monkey_off_32x32.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/monkey_off_64x64.png b/tests/manual/examples/widgets/widgets/icons/images/monkey_off_64x64.png
new file mode 100644
index 0000000000..47d8f6de35
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/monkey_off_64x64.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/monkey_on_128x128.png b/tests/manual/examples/widgets/widgets/icons/images/monkey_on_128x128.png
new file mode 100644
index 0000000000..8e1c7468bf
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/monkey_on_128x128.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/monkey_on_16x16.png b/tests/manual/examples/widgets/widgets/icons/images/monkey_on_16x16.png
new file mode 100644
index 0000000000..082e8527f1
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/monkey_on_16x16.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/monkey_on_32x32.png b/tests/manual/examples/widgets/widgets/icons/images/monkey_on_32x32.png
new file mode 100644
index 0000000000..bf9acc6cae
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/monkey_on_32x32.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/monkey_on_64x64.png b/tests/manual/examples/widgets/widgets/icons/images/monkey_on_64x64.png
new file mode 100644
index 0000000000..990f604d98
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/monkey_on_64x64.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/qt_extended_16x16.png b/tests/manual/examples/widgets/widgets/icons/images/qt_extended_16x16.png
new file mode 100644
index 0000000000..30bcb45ed2
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/qt_extended_16x16.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/qt_extended_32x32.png b/tests/manual/examples/widgets/widgets/icons/images/qt_extended_32x32.png
new file mode 100644
index 0000000000..d609c1e1e5
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/qt_extended_32x32.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/images/qt_extended_48x48.png b/tests/manual/examples/widgets/widgets/icons/images/qt_extended_48x48.png
new file mode 100644
index 0000000000..0e524fed5f
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/images/qt_extended_48x48.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/icons/main.cpp b/tests/manual/examples/widgets/widgets/icons/main.cpp
new file mode 100644
index 0000000000..b7ed18ff94
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/main.cpp
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QApplication>
+#include <QCommandLineParser>
+#include <QScreen>
+
+#include "mainwindow.h"
+
+//! [45]
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ QCoreApplication::setApplicationName(MainWindow::tr("Icons"));
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QCommandLineParser commandLineParser;
+ commandLineParser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
+ commandLineParser.addHelpOption();
+ commandLineParser.addVersionOption();
+ commandLineParser.addPositionalArgument(MainWindow::tr("[file]"), MainWindow::tr("Icon file(s) to open."));
+ commandLineParser.process(QCoreApplication::arguments());
+
+ MainWindow mainWin;
+ if (!commandLineParser.positionalArguments().isEmpty())
+ mainWin.loadImages(commandLineParser.positionalArguments());
+
+ const QRect availableGeometry = mainWin.screen()->availableGeometry();
+ mainWin.resize(availableGeometry.width() / 2, availableGeometry.height() * 2 / 3);
+ mainWin.move((availableGeometry.width() - mainWin.width()) / 2, (availableGeometry.height() - mainWin.height()) / 2);
+
+ mainWin.show();
+ return app.exec();
+}
+//! [45]
diff --git a/tests/manual/examples/widgets/widgets/icons/mainwindow.cpp b/tests/manual/examples/widgets/widgets/icons/mainwindow.cpp
new file mode 100644
index 0000000000..f893575f76
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/mainwindow.cpp
@@ -0,0 +1,478 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "mainwindow.h"
+#include "iconpreviewarea.h"
+#include "iconsizespinbox.h"
+#include "imagedelegate.h"
+
+#include <QActionGroup>
+#include <QApplication>
+#include <QButtonGroup>
+#include <QCheckBox>
+#include <QFileDialog>
+#include <QHeaderView>
+#include <QFormLayout>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QImageReader>
+#include <QLabel>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QRadioButton>
+#include <QScreen>
+#include <QStandardPaths>
+#include <QStyleFactory>
+#include <QTableWidget>
+#include <QWindow>
+
+//! [40]
+enum { OtherSize = QStyle::PM_CustomBase };
+//! [40]
+
+//! [0]
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+{
+ QWidget *centralWidget = new QWidget(this);
+ setCentralWidget(centralWidget);
+
+ createActions();
+
+ QGridLayout *mainLayout = new QGridLayout(centralWidget);
+
+ QGroupBox *previewGroupBox = new QGroupBox(tr("Preview"));
+ previewArea = new IconPreviewArea(previewGroupBox);
+ QVBoxLayout *previewLayout = new QVBoxLayout(previewGroupBox);
+ previewLayout->addWidget(previewArea);
+
+ mainLayout->addWidget(previewGroupBox, 0, 0, 1, 2);
+ mainLayout->addWidget(createImagesGroupBox(), 1, 0);
+ QVBoxLayout *vBox = new QVBoxLayout;
+ vBox->addWidget(createIconSizeGroupBox());
+ vBox->addWidget(createHighDpiIconSizeGroupBox());
+ vBox->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
+ mainLayout->addLayout(vBox, 1, 1);
+ createContextMenu();
+
+ setWindowTitle(tr("Icons"));
+ checkCurrentStyle();
+ sizeButtonGroup->button(OtherSize)->click();
+}
+//! [0]
+
+//! [44]
+void MainWindow::show()
+{
+ QMainWindow::show();
+ connect(windowHandle(), &QWindow::screenChanged, this, &MainWindow::screenChanged);
+ screenChanged();
+}
+//! [44]
+
+//! [1]
+void MainWindow::about()
+{
+ QMessageBox::about(this, tr("About Icons"),
+ tr("The <b>Icons</b> example illustrates how Qt renders an icon in "
+ "different modes (active, normal, disabled, and selected) and "
+ "states (on and off) based on a set of images."));
+}
+//! [1]
+
+//! [2]
+void MainWindow::changeStyle(bool checked)
+{
+ if (!checked)
+ return;
+
+ const QAction *action = qobject_cast<QAction *>(sender());
+//! [2] //! [3]
+ QStyle *style = QStyleFactory::create(action->data().toString());
+//! [3] //! [4]
+ Q_ASSERT(style);
+ QApplication::setStyle(style);
+
+ const QList<QAbstractButton*> buttons = sizeButtonGroup->buttons();
+ for (QAbstractButton *button : buttons) {
+ const QStyle::PixelMetric metric = static_cast<QStyle::PixelMetric>(sizeButtonGroup->id(button));
+ const int value = style->pixelMetric(metric);
+ switch (metric) {
+ case QStyle::PM_SmallIconSize:
+ button->setText(tr("Small (%1 x %1)").arg(value));
+ break;
+ case QStyle::PM_LargeIconSize:
+ button->setText(tr("Large (%1 x %1)").arg(value));
+ break;
+ case QStyle::PM_ToolBarIconSize:
+ button->setText(tr("Toolbars (%1 x %1)").arg(value));
+ break;
+ case QStyle::PM_ListViewIconSize:
+ button->setText(tr("List views (%1 x %1)").arg(value));
+ break;
+ case QStyle::PM_IconViewIconSize:
+ button->setText(tr("Icon views (%1 x %1)").arg(value));
+ break;
+ case QStyle::PM_TabBarIconSize:
+ button->setText(tr("Tab bars (%1 x %1)").arg(value));
+ break;
+ default:
+ break;
+ }
+ }
+
+ triggerChangeSize();
+}
+//! [4]
+
+//! [5]
+void MainWindow::changeSize(QAbstractButton *button, bool checked)
+{
+ if (!checked)
+ return;
+
+ const int index = sizeButtonGroup->id(button);
+ const bool other = index == int(OtherSize);
+ const int extent = other
+ ? otherSpinBox->value()
+ : QApplication::style()->pixelMetric(static_cast<QStyle::PixelMetric>(index));
+
+ previewArea->setSize(QSize(extent, extent));
+ otherSpinBox->setEnabled(other);
+}
+
+void MainWindow::triggerChangeSize()
+{
+ changeSize(sizeButtonGroup->checkedButton(), true);
+}
+//! [5]
+
+//! [6]
+void MainWindow::changeIcon()
+{
+ QIcon icon;
+
+ for (int row = 0; row < imagesTable->rowCount(); ++row) {
+ const QTableWidgetItem *fileItem = imagesTable->item(row, 0);
+ const QTableWidgetItem *modeItem = imagesTable->item(row, 1);
+ const QTableWidgetItem *stateItem = imagesTable->item(row, 2);
+
+ if (fileItem->checkState() == Qt::Checked) {
+ const int modeIndex = IconPreviewArea::iconModeNames().indexOf(modeItem->text());
+ Q_ASSERT(modeIndex >= 0);
+ const int stateIndex = IconPreviewArea::iconStateNames().indexOf(stateItem->text());
+ Q_ASSERT(stateIndex >= 0);
+ const QIcon::Mode mode = IconPreviewArea::iconModes().at(modeIndex);
+ const QIcon::State state = IconPreviewArea::iconStates().at(stateIndex);
+//! [6]
+
+//! [8]
+ const QString fileName = fileItem->data(Qt::UserRole).toString();
+ QImage image(fileName);
+ if (!image.isNull())
+ icon.addPixmap(QPixmap::fromImage(image), mode, state);
+//! [8]
+ }
+ }
+//! [11]
+ previewArea->setIcon(icon);
+//! [11]
+}
+
+void MainWindow::addSampleImages()
+{
+ addImages(QLatin1String(SRCDIR) + QLatin1String("/images"));
+}
+
+void MainWindow::addOtherImages()
+{
+ static bool firstInvocation = true;
+ QString directory;
+ if (firstInvocation) {
+ firstInvocation = false;
+ directory = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation).value(0, QString());
+ }
+ addImages(directory);
+}
+
+//! [12]
+void MainWindow::addImages(const QString &directory)
+{
+ QFileDialog fileDialog(this, tr("Open Images"), directory);
+ QStringList mimeTypeFilters;
+ const QList<QByteArray> mimeTypes = QImageReader::supportedMimeTypes();
+ for (const QByteArray &mimeTypeName : mimeTypes)
+ mimeTypeFilters.append(mimeTypeName);
+ mimeTypeFilters.sort();
+ fileDialog.setMimeTypeFilters(mimeTypeFilters);
+ fileDialog.selectMimeTypeFilter(QLatin1String("image/png"));
+ fileDialog.setAcceptMode(QFileDialog::AcceptOpen);
+ fileDialog.setFileMode(QFileDialog::ExistingFiles);
+ if (!nativeFileDialogAct->isChecked())
+ fileDialog.setOption(QFileDialog::DontUseNativeDialog);
+ if (fileDialog.exec() == QDialog::Accepted)
+ loadImages(fileDialog.selectedFiles());
+//! [12]
+}
+
+void MainWindow::loadImages(const QStringList &fileNames)
+{
+ for (const QString &fileName : fileNames) {
+ const int row = imagesTable->rowCount();
+ imagesTable->setRowCount(row + 1);
+//! [13]
+ const QFileInfo fileInfo(fileName);
+ const QString imageName = fileInfo.baseName();
+ const QString fileName2x = fileInfo.absolutePath()
+ + QLatin1Char('/') + imageName + QLatin1String("@2x.") + fileInfo.suffix();
+ const QFileInfo fileInfo2x(fileName2x);
+ const QImage image(fileName);
+ const QString toolTip =
+ tr("Directory: %1\nFile: %2\nFile@2x: %3\nSize: %4x%5")
+ .arg(QDir::toNativeSeparators(fileInfo.absolutePath()), fileInfo.fileName())
+ .arg(fileInfo2x.exists() ? fileInfo2x.fileName() : tr("<None>"))
+ .arg(image.width()).arg(image.height());
+ QTableWidgetItem *fileItem = new QTableWidgetItem(imageName);
+ fileItem->setData(Qt::UserRole, fileName);
+ fileItem->setIcon(QPixmap::fromImage(image));
+ fileItem->setFlags((fileItem->flags() | Qt::ItemIsUserCheckable) & ~Qt::ItemIsEditable);
+ fileItem->setToolTip(toolTip);
+//! [13]
+
+//! [15]
+ QIcon::Mode mode = QIcon::Normal;
+ QIcon::State state = QIcon::Off;
+ if (guessModeStateAct->isChecked()) {
+ if (imageName.contains(QLatin1String("_act"), Qt::CaseInsensitive))
+ mode = QIcon::Active;
+ else if (imageName.contains(QLatin1String("_dis"), Qt::CaseInsensitive))
+ mode = QIcon::Disabled;
+ else if (imageName.contains(QLatin1String("_sel"), Qt::CaseInsensitive))
+ mode = QIcon::Selected;
+
+ if (imageName.contains(QLatin1String("_on"), Qt::CaseInsensitive))
+ state = QIcon::On;
+//! [15]
+ }
+
+//! [18]
+ imagesTable->setItem(row, 0, fileItem);
+ QTableWidgetItem *modeItem =
+ new QTableWidgetItem(IconPreviewArea::iconModeNames().at(IconPreviewArea::iconModes().indexOf(mode)));
+ modeItem->setToolTip(toolTip);
+ imagesTable->setItem(row, 1, modeItem);
+ QTableWidgetItem *stateItem =
+ new QTableWidgetItem(IconPreviewArea::iconStateNames().at(IconPreviewArea::iconStates().indexOf(state)));
+ stateItem->setToolTip(toolTip);
+ imagesTable->setItem(row, 2, stateItem);
+ imagesTable->openPersistentEditor(modeItem);
+ imagesTable->openPersistentEditor(stateItem);
+
+ fileItem->setCheckState(Qt::Checked);
+//! [18]
+ }
+}
+
+//! [20]
+void MainWindow::removeAllImages()
+{
+ imagesTable->setRowCount(0);
+ changeIcon();
+}
+//! [20]
+
+//! [21]
+QWidget *MainWindow::createImagesGroupBox()
+{
+ QGroupBox *imagesGroupBox = new QGroupBox(tr("Images"));
+
+ imagesTable = new QTableWidget;
+ imagesTable->setSelectionMode(QAbstractItemView::NoSelection);
+ imagesTable->setItemDelegate(new ImageDelegate(this));
+//! [21]
+
+//! [22]
+ const QStringList labels({tr("Image"), tr("Mode"), tr("State")});
+
+ imagesTable->horizontalHeader()->setDefaultSectionSize(90);
+ imagesTable->setColumnCount(3);
+ imagesTable->setHorizontalHeaderLabels(labels);
+ imagesTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
+ imagesTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
+ imagesTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Fixed);
+ imagesTable->verticalHeader()->hide();
+//! [22]
+
+//! [24]
+ connect(imagesTable, &QTableWidget::itemChanged,
+ this, &MainWindow::changeIcon);
+
+ QVBoxLayout *layout = new QVBoxLayout(imagesGroupBox);
+ layout->addWidget(imagesTable);
+ return imagesGroupBox;
+//! [24]
+}
+
+//! [26]
+QWidget *MainWindow::createIconSizeGroupBox()
+{
+ QGroupBox *iconSizeGroupBox = new QGroupBox(tr("Icon Size"));
+
+ sizeButtonGroup = new QButtonGroup(this);
+ sizeButtonGroup->setExclusive(true);
+
+ connect(sizeButtonGroup, &QButtonGroup::buttonToggled,
+ this, &MainWindow::changeSize);
+
+ QRadioButton *smallRadioButton = new QRadioButton;
+ sizeButtonGroup->addButton(smallRadioButton, QStyle::PM_SmallIconSize);
+ QRadioButton *largeRadioButton = new QRadioButton;
+ sizeButtonGroup->addButton(largeRadioButton, QStyle::PM_LargeIconSize);
+ QRadioButton *toolBarRadioButton = new QRadioButton;
+ sizeButtonGroup->addButton(toolBarRadioButton, QStyle::PM_ToolBarIconSize);
+ QRadioButton *listViewRadioButton = new QRadioButton;
+ sizeButtonGroup->addButton(listViewRadioButton, QStyle::PM_ListViewIconSize);
+ QRadioButton *iconViewRadioButton = new QRadioButton;
+ sizeButtonGroup->addButton(iconViewRadioButton, QStyle::PM_IconViewIconSize);
+ QRadioButton *tabBarRadioButton = new QRadioButton;
+ sizeButtonGroup->addButton(tabBarRadioButton, QStyle::PM_TabBarIconSize);
+ QRadioButton *otherRadioButton = new QRadioButton(tr("Other:"));
+ sizeButtonGroup->addButton(otherRadioButton, OtherSize);
+ otherSpinBox = new IconSizeSpinBox;
+ otherSpinBox->setRange(8, 256);
+ const QString spinBoxToolTip =
+ tr("Enter a custom size within %1..%2")
+ .arg(otherSpinBox->minimum()).arg(otherSpinBox->maximum());
+ otherSpinBox->setValue(64);
+ otherSpinBox->setToolTip(spinBoxToolTip);
+ otherRadioButton->setToolTip(spinBoxToolTip);
+//! [26]
+
+//! [27]
+ connect(otherSpinBox, &QSpinBox::valueChanged,
+ this, &MainWindow::triggerChangeSize);
+
+ QHBoxLayout *otherSizeLayout = new QHBoxLayout;
+ otherSizeLayout->addWidget(otherRadioButton);
+ otherSizeLayout->addWidget(otherSpinBox);
+ otherSizeLayout->addStretch();
+
+ QGridLayout *layout = new QGridLayout(iconSizeGroupBox);
+ layout->addWidget(smallRadioButton, 0, 0);
+ layout->addWidget(largeRadioButton, 1, 0);
+ layout->addWidget(toolBarRadioButton, 2, 0);
+ layout->addWidget(listViewRadioButton, 0, 1);
+ layout->addWidget(iconViewRadioButton, 1, 1);
+ layout->addWidget(tabBarRadioButton, 2, 1);
+ layout->addLayout(otherSizeLayout, 3, 0, 1, 2);
+ layout->setRowStretch(4, 1);
+ return iconSizeGroupBox;
+//! [27]
+}
+
+void MainWindow::screenChanged()
+{
+ devicePixelRatioLabel->setText(QString::number(devicePixelRatio()));
+ if (const QWindow *window = windowHandle()) {
+ const QScreen *screen = window->screen();
+ const QString screenDescription =
+ tr("\"%1\" (%2x%3)").arg(screen->name())
+ .arg(screen->geometry().width()).arg(screen->geometry().height());
+ screenNameLabel->setText(screenDescription);
+ }
+ changeIcon();
+}
+
+QWidget *MainWindow::createHighDpiIconSizeGroupBox()
+{
+ QGroupBox *highDpiGroupBox = new QGroupBox(tr("High DPI Scaling"));
+ QFormLayout *layout = new QFormLayout(highDpiGroupBox);
+ devicePixelRatioLabel = new QLabel(highDpiGroupBox);
+ screenNameLabel = new QLabel(highDpiGroupBox);
+ layout->addRow(tr("Screen:"), screenNameLabel);
+ layout->addRow(tr("Device pixel ratio:"), devicePixelRatioLabel);
+ return highDpiGroupBox;
+}
+
+//! [28]
+void MainWindow::createActions()
+{
+ QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
+
+ addSampleImagesAct = new QAction(tr("Add &Sample Images..."), this);
+ addSampleImagesAct->setShortcut(tr("Ctrl+A"));
+ connect(addSampleImagesAct, &QAction::triggered, this, &MainWindow::addSampleImages);
+ fileMenu->addAction(addSampleImagesAct);
+
+ addOtherImagesAct = new QAction(tr("&Add Images..."), this);
+ addOtherImagesAct->setShortcut(QKeySequence::Open);
+ connect(addOtherImagesAct, &QAction::triggered, this, &MainWindow::addOtherImages);
+ fileMenu->addAction(addOtherImagesAct);
+
+ removeAllImagesAct = new QAction(tr("&Remove All Images"), this);
+ removeAllImagesAct->setShortcut(tr("Ctrl+R"));
+ connect(removeAllImagesAct, &QAction::triggered,
+ this, &MainWindow::removeAllImages);
+ fileMenu->addAction(removeAllImagesAct);
+
+ fileMenu->addSeparator();
+
+ QAction *exitAct = fileMenu->addAction(tr("&Quit"), qApp, &QCoreApplication::quit);
+ exitAct->setShortcuts(QKeySequence::Quit);
+
+ QMenu *viewMenu = menuBar()->addMenu(tr("&View"));
+
+ styleActionGroup = new QActionGroup(this);
+ const QStringList styleKeys = QStyleFactory::keys();
+ for (const QString &styleName : styleKeys) {
+ QAction *action = new QAction(tr("%1 Style").arg(styleName), styleActionGroup);
+ action->setData(styleName);
+ action->setCheckable(true);
+ connect(action, &QAction::triggered, this, &MainWindow::changeStyle);
+ viewMenu->addAction(action);
+ }
+
+ QMenu *settingsMenu = menuBar()->addMenu(tr("&Settings"));
+
+ guessModeStateAct = new QAction(tr("&Guess Image Mode/State"), this);
+ guessModeStateAct->setCheckable(true);
+ guessModeStateAct->setChecked(true);
+ settingsMenu->addAction(guessModeStateAct);
+
+ nativeFileDialogAct = new QAction(tr("&Use Native File Dialog"), this);
+ nativeFileDialogAct->setCheckable(true);
+ nativeFileDialogAct->setChecked(true);
+ settingsMenu->addAction(nativeFileDialogAct);
+
+ QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
+ helpMenu->addAction(tr("&About"), this, &MainWindow::about);
+ helpMenu->addAction(tr("About &Qt"), qApp, &QApplication::aboutQt);
+}
+//! [28]
+
+//! [30]
+void MainWindow::createContextMenu()
+{
+ imagesTable->setContextMenuPolicy(Qt::ActionsContextMenu);
+ imagesTable->addAction(addSampleImagesAct);
+ imagesTable->addAction(addOtherImagesAct);
+ imagesTable->addAction(removeAllImagesAct);
+}
+//! [30]
+
+//! [31]
+void MainWindow::checkCurrentStyle()
+{
+ const QList<QAction *> actions = styleActionGroup->actions();
+ for (QAction *action : actions) {
+ const QString styleName = action->data().toString();
+ const std::unique_ptr<QStyle> candidate{QStyleFactory::create(styleName)};
+ Q_ASSERT(candidate);
+ if (candidate->metaObject()->className()
+ == QApplication::style()->metaObject()->className()) {
+ action->trigger();
+ return;
+ }
+ }
+}
+//! [31]
diff --git a/tests/manual/examples/widgets/widgets/icons/mainwindow.h b/tests/manual/examples/widgets/widgets/icons/mainwindow.h
new file mode 100644
index 0000000000..fb6e0493f7
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/icons/mainwindow.h
@@ -0,0 +1,74 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QIcon>
+#include <QList>
+#include <QMainWindow>
+#include <QPixmap>
+
+QT_BEGIN_NAMESPACE
+class QAction;
+class QActionGroup;
+class QLabel;
+class QButtonGroup;
+class QTableWidget;
+class QAbstractButton;
+QT_END_NAMESPACE
+class IconPreviewArea;
+class IconSizeSpinBox;
+
+//! [0]
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = nullptr);
+
+ void loadImages(const QStringList &fileNames);
+
+ void show();
+
+private slots:
+ void about();
+ void changeStyle(bool checked);
+ void changeSize(QAbstractButton *button, bool);
+ void triggerChangeSize();
+ void changeIcon();
+ void addSampleImages();
+ void addOtherImages();
+ void removeAllImages();
+ void screenChanged();
+
+private:
+ QWidget *createImagesGroupBox();
+ QWidget *createIconSizeGroupBox();
+ QWidget *createHighDpiIconSizeGroupBox();
+ void createActions();
+ void createContextMenu();
+ void checkCurrentStyle();
+ void addImages(const QString &directory);
+
+ IconPreviewArea *previewArea;
+
+ QTableWidget *imagesTable;
+
+ QButtonGroup *sizeButtonGroup;
+ IconSizeSpinBox *otherSpinBox;
+
+ QLabel *devicePixelRatioLabel;
+ QLabel *screenNameLabel;
+
+ QAction *addOtherImagesAct;
+ QAction *addSampleImagesAct;
+ QAction *removeAllImagesAct;
+ QAction *guessModeStateAct;
+ QAction *nativeFileDialogAct;
+ QActionGroup *styleActionGroup;
+};
+//! [0]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/imageviewer/CMakeLists.txt b/tests/manual/examples/widgets/widgets/imageviewer/CMakeLists.txt
new file mode 100644
index 0000000000..fd2f051210
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/imageviewer/CMakeLists.txt
@@ -0,0 +1,44 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(imageviewer LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/imageviewer")
+
+find_package(Qt6
+ REQUIRED COMPONENTS Core Gui Widgets
+ OPTIONAL_COMPONENTS PrintSupport
+)
+
+qt_standard_project_setup()
+
+qt_add_executable(imageviewer
+ imageviewer.cpp imageviewer.h
+ main.cpp
+)
+
+set_target_properties(imageviewer PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(imageviewer PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+)
+
+if (TARGET Qt6::PrintSupport)
+ target_link_libraries(imageviewer PRIVATE Qt6::PrintSupport)
+endif()
+
+install(TARGETS imageviewer
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/tests/manual/examples/widgets/widgets/imageviewer/imageviewer.cpp b/tests/manual/examples/widgets/widgets/imageviewer/imageviewer.cpp
new file mode 100644
index 0000000000..72a93dbf1b
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/imageviewer/imageviewer.cpp
@@ -0,0 +1,364 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "imageviewer.h"
+
+#include <QApplication>
+#include <QClipboard>
+#include <QColorSpace>
+#include <QDir>
+#include <QFileDialog>
+#include <QImageReader>
+#include <QImageWriter>
+#include <QLabel>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QMimeData>
+#include <QPainter>
+#include <QScreen>
+#include <QScrollArea>
+#include <QScrollBar>
+#include <QStandardPaths>
+#include <QStatusBar>
+
+#if defined(QT_PRINTSUPPORT_LIB)
+# include <QtPrintSupport/qtprintsupportglobal.h>
+
+# if QT_CONFIG(printdialog)
+# include <QPrintDialog>
+# endif
+#endif
+
+//! [0]
+ImageViewer::ImageViewer(QWidget *parent)
+ : QMainWindow(parent), imageLabel(new QLabel)
+ , scrollArea(new QScrollArea)
+{
+ imageLabel->setBackgroundRole(QPalette::Base);
+ imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+ imageLabel->setScaledContents(true);
+
+ scrollArea->setBackgroundRole(QPalette::Dark);
+ scrollArea->setWidget(imageLabel);
+ scrollArea->setVisible(false);
+ setCentralWidget(scrollArea);
+
+ createActions();
+
+ resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);
+}
+
+//! [0]
+//! [2]
+
+bool ImageViewer::loadFile(const QString &fileName)
+{
+ QImageReader reader(fileName);
+ reader.setAutoTransform(true);
+ const QImage newImage = reader.read();
+ if (newImage.isNull()) {
+ QMessageBox::information(this, QGuiApplication::applicationDisplayName(),
+ tr("Cannot load %1: %2")
+ .arg(QDir::toNativeSeparators(fileName), reader.errorString()));
+ return false;
+ }
+//! [2]
+
+ setImage(newImage);
+
+ setWindowFilePath(fileName);
+
+ const QString description = image.colorSpace().isValid()
+ ? image.colorSpace().description() : tr("unknown");
+ const QString message = tr("Opened \"%1\", %2x%3, Depth: %4 (%5)")
+ .arg(QDir::toNativeSeparators(fileName)).arg(image.width()).arg(image.height())
+ .arg(image.depth()).arg(description);
+ statusBar()->showMessage(message);
+ return true;
+}
+
+void ImageViewer::setImage(const QImage &newImage)
+{
+ if (newImage.colorSpace().isValid())
+ image = newImage.convertedToColorSpace(QColorSpace::SRgb);
+ else
+ image = newImage;
+ imageLabel->setPixmap(QPixmap::fromImage(image, Qt::NoFormatConversion));
+//! [4]
+ scaleFactor = 1.0;
+
+ scrollArea->setVisible(true);
+ printAct->setEnabled(true);
+ fitToWindowAct->setEnabled(true);
+ updateActions();
+
+ if (!fitToWindowAct->isChecked())
+ imageLabel->adjustSize();
+}
+
+//! [4]
+
+bool ImageViewer::saveFile(const QString &fileName)
+{
+ QImageWriter writer(fileName);
+
+ if (!writer.write(image)) {
+ QMessageBox::information(this, QGuiApplication::applicationDisplayName(),
+ tr("Cannot write %1: %2")
+ .arg(QDir::toNativeSeparators(fileName), writer.errorString()));
+ return false;
+ }
+ const QString message = tr("Wrote \"%1\"").arg(QDir::toNativeSeparators(fileName));
+ statusBar()->showMessage(message);
+ return true;
+}
+
+//! [1]
+
+static void initializeImageFileDialog(QFileDialog &dialog, QFileDialog::AcceptMode acceptMode)
+{
+ static bool firstDialog = true;
+
+ if (firstDialog) {
+ firstDialog = false;
+ const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
+ dialog.setDirectory(picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.last());
+ }
+
+ QStringList mimeTypeFilters;
+ const QByteArrayList supportedMimeTypes = acceptMode == QFileDialog::AcceptOpen
+ ? QImageReader::supportedMimeTypes() : QImageWriter::supportedMimeTypes();
+ for (const QByteArray &mimeTypeName : supportedMimeTypes)
+ mimeTypeFilters.append(mimeTypeName);
+ mimeTypeFilters.sort();
+ dialog.setMimeTypeFilters(mimeTypeFilters);
+ dialog.selectMimeTypeFilter("image/jpeg");
+ dialog.setAcceptMode(acceptMode);
+ if (acceptMode == QFileDialog::AcceptSave)
+ dialog.setDefaultSuffix("jpg");
+}
+
+void ImageViewer::open()
+{
+ QFileDialog dialog(this, tr("Open File"));
+ initializeImageFileDialog(dialog, QFileDialog::AcceptOpen);
+
+ while (dialog.exec() == QDialog::Accepted && !loadFile(dialog.selectedFiles().constFirst())) {}
+}
+//! [1]
+
+void ImageViewer::saveAs()
+{
+ QFileDialog dialog(this, tr("Save File As"));
+ initializeImageFileDialog(dialog, QFileDialog::AcceptSave);
+
+ while (dialog.exec() == QDialog::Accepted && !saveFile(dialog.selectedFiles().constFirst())) {}
+}
+
+//! [5]
+void ImageViewer::print()
+//! [5] //! [6]
+{
+ Q_ASSERT(!imageLabel->pixmap().isNull());
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printdialog)
+//! [6] //! [7]
+ QPrintDialog dialog(&printer, this);
+//! [7] //! [8]
+ if (dialog.exec()) {
+ QPainter painter(&printer);
+ QPixmap pixmap = imageLabel->pixmap();
+ QRect rect = painter.viewport();
+ QSize size = pixmap.size();
+ size.scale(rect.size(), Qt::KeepAspectRatio);
+ painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
+ painter.setWindow(pixmap.rect());
+ painter.drawPixmap(0, 0, pixmap);
+ }
+#endif
+}
+//! [8]
+
+void ImageViewer::copy()
+{
+#ifndef QT_NO_CLIPBOARD
+ QGuiApplication::clipboard()->setImage(image);
+#endif // !QT_NO_CLIPBOARD
+}
+
+#ifndef QT_NO_CLIPBOARD
+static QImage clipboardImage()
+{
+ if (const QMimeData *mimeData = QGuiApplication::clipboard()->mimeData()) {
+ if (mimeData->hasImage()) {
+ const QImage image = qvariant_cast<QImage>(mimeData->imageData());
+ if (!image.isNull())
+ return image;
+ }
+ }
+ return QImage();
+}
+#endif // !QT_NO_CLIPBOARD
+
+void ImageViewer::paste()
+{
+#ifndef QT_NO_CLIPBOARD
+ const QImage newImage = clipboardImage();
+ if (newImage.isNull()) {
+ statusBar()->showMessage(tr("No image in clipboard"));
+ } else {
+ setImage(newImage);
+ setWindowFilePath(QString());
+ const QString message = tr("Obtained image from clipboard, %1x%2, Depth: %3")
+ .arg(newImage.width()).arg(newImage.height()).arg(newImage.depth());
+ statusBar()->showMessage(message);
+ }
+#endif // !QT_NO_CLIPBOARD
+}
+
+//! [9]
+void ImageViewer::zoomIn()
+//! [9] //! [10]
+{
+ scaleImage(1.25);
+}
+
+void ImageViewer::zoomOut()
+{
+ scaleImage(0.8);
+}
+
+//! [10] //! [11]
+void ImageViewer::normalSize()
+//! [11] //! [12]
+{
+ imageLabel->adjustSize();
+ scaleFactor = 1.0;
+}
+//! [12]
+
+//! [13]
+void ImageViewer::fitToWindow()
+//! [13] //! [14]
+{
+ bool fitToWindow = fitToWindowAct->isChecked();
+ scrollArea->setWidgetResizable(fitToWindow);
+ if (!fitToWindow)
+ normalSize();
+ updateActions();
+}
+//! [14]
+
+
+//! [15]
+void ImageViewer::about()
+//! [15] //! [16]
+{
+ QMessageBox::about(this, tr("About Image Viewer"),
+ tr("<p>The <b>Image Viewer</b> example shows how to combine QLabel "
+ "and QScrollArea to display an image. QLabel is typically used "
+ "for displaying a text, but it can also display an image. "
+ "QScrollArea provides a scrolling view around another widget. "
+ "If the child widget exceeds the size of the frame, QScrollArea "
+ "automatically provides scroll bars. </p><p>The example "
+ "demonstrates how QLabel's ability to scale its contents "
+ "(QLabel::scaledContents), and QScrollArea's ability to "
+ "automatically resize its contents "
+ "(QScrollArea::widgetResizable), can be used to implement "
+ "zooming and scaling features. </p><p>In addition the example "
+ "shows how to use QPainter to print an image.</p>"));
+}
+//! [16]
+
+//! [17]
+void ImageViewer::createActions()
+//! [17] //! [18]
+{
+ QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
+
+ QAction *openAct = fileMenu->addAction(tr("&Open..."), this, &ImageViewer::open);
+ openAct->setShortcut(QKeySequence::Open);
+
+ saveAsAct = fileMenu->addAction(tr("&Save As..."), this, &ImageViewer::saveAs);
+ saveAsAct->setEnabled(false);
+
+ printAct = fileMenu->addAction(tr("&Print..."), this, &ImageViewer::print);
+ printAct->setShortcut(QKeySequence::Print);
+ printAct->setEnabled(false);
+
+ fileMenu->addSeparator();
+
+ QAction *exitAct = fileMenu->addAction(tr("E&xit"), this, &QWidget::close);
+ exitAct->setShortcut(tr("Ctrl+Q"));
+
+ QMenu *editMenu = menuBar()->addMenu(tr("&Edit"));
+
+ copyAct = editMenu->addAction(tr("&Copy"), this, &ImageViewer::copy);
+ copyAct->setShortcut(QKeySequence::Copy);
+ copyAct->setEnabled(false);
+
+ QAction *pasteAct = editMenu->addAction(tr("&Paste"), this, &ImageViewer::paste);
+ pasteAct->setShortcut(QKeySequence::Paste);
+
+ QMenu *viewMenu = menuBar()->addMenu(tr("&View"));
+
+ zoomInAct = viewMenu->addAction(tr("Zoom &In (25%)"), this, &ImageViewer::zoomIn);
+ zoomInAct->setShortcut(QKeySequence::ZoomIn);
+ zoomInAct->setEnabled(false);
+
+ zoomOutAct = viewMenu->addAction(tr("Zoom &Out (25%)"), this, &ImageViewer::zoomOut);
+ zoomOutAct->setShortcut(QKeySequence::ZoomOut);
+ zoomOutAct->setEnabled(false);
+
+ normalSizeAct = viewMenu->addAction(tr("&Normal Size"), this, &ImageViewer::normalSize);
+ normalSizeAct->setShortcut(tr("Ctrl+S"));
+ normalSizeAct->setEnabled(false);
+
+ viewMenu->addSeparator();
+
+ fitToWindowAct = viewMenu->addAction(tr("&Fit to Window"), this, &ImageViewer::fitToWindow);
+ fitToWindowAct->setEnabled(false);
+ fitToWindowAct->setCheckable(true);
+ fitToWindowAct->setShortcut(tr("Ctrl+F"));
+
+ QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
+
+ helpMenu->addAction(tr("&About"), this, &ImageViewer::about);
+ helpMenu->addAction(tr("About &Qt"), this, &QApplication::aboutQt);
+}
+//! [18]
+
+//! [21]
+void ImageViewer::updateActions()
+//! [21] //! [22]
+{
+ saveAsAct->setEnabled(!image.isNull());
+ copyAct->setEnabled(!image.isNull());
+ zoomInAct->setEnabled(!fitToWindowAct->isChecked());
+ zoomOutAct->setEnabled(!fitToWindowAct->isChecked());
+ normalSizeAct->setEnabled(!fitToWindowAct->isChecked());
+}
+//! [22]
+
+//! [23]
+void ImageViewer::scaleImage(double factor)
+//! [23] //! [24]
+{
+ scaleFactor *= factor;
+ imageLabel->resize(scaleFactor * imageLabel->pixmap().size());
+
+ adjustScrollBar(scrollArea->horizontalScrollBar(), factor);
+ adjustScrollBar(scrollArea->verticalScrollBar(), factor);
+
+ zoomInAct->setEnabled(scaleFactor < 3.0);
+ zoomOutAct->setEnabled(scaleFactor > 0.333);
+}
+//! [24]
+
+//! [25]
+void ImageViewer::adjustScrollBar(QScrollBar *scrollBar, double factor)
+//! [25] //! [26]
+{
+ scrollBar->setValue(int(factor * scrollBar->value()
+ + ((factor - 1) * scrollBar->pageStep()/2)));
+}
+//! [26]
diff --git a/tests/manual/examples/widgets/widgets/imageviewer/imageviewer.h b/tests/manual/examples/widgets/widgets/imageviewer/imageviewer.h
new file mode 100644
index 0000000000..e9e6858c74
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/imageviewer/imageviewer.h
@@ -0,0 +1,74 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef IMAGEVIEWER_H
+#define IMAGEVIEWER_H
+
+#include <QMainWindow>
+#include <QImage>
+#if defined(QT_PRINTSUPPORT_LIB)
+# include <QtPrintSupport/qtprintsupportglobal.h>
+
+# if QT_CONFIG(printer)
+# include <QPrinter>
+# endif
+#endif
+
+QT_BEGIN_NAMESPACE
+class QAction;
+class QLabel;
+class QMenu;
+class QScrollArea;
+class QScrollBar;
+QT_END_NAMESPACE
+
+//! [0]
+class ImageViewer : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ ImageViewer(QWidget *parent = nullptr);
+ bool loadFile(const QString &);
+
+private slots:
+ void open();
+ void saveAs();
+ void print();
+ void copy();
+ void paste();
+ void zoomIn();
+ void zoomOut();
+ void normalSize();
+ void fitToWindow();
+ void about();
+
+private:
+ void createActions();
+ void createMenus();
+ void updateActions();
+ bool saveFile(const QString &fileName);
+ void setImage(const QImage &newImage);
+ void scaleImage(double factor);
+ void adjustScrollBar(QScrollBar *scrollBar, double factor);
+
+ QImage image;
+ QLabel *imageLabel;
+ QScrollArea *scrollArea;
+ double scaleFactor = 1;
+
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer)
+ QPrinter printer;
+#endif
+
+ QAction *saveAsAct;
+ QAction *printAct;
+ QAction *copyAct;
+ QAction *zoomInAct;
+ QAction *zoomOutAct;
+ QAction *normalSizeAct;
+ QAction *fitToWindowAct;
+};
+//! [0]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/imageviewer/imageviewer.pro b/tests/manual/examples/widgets/widgets/imageviewer/imageviewer.pro
new file mode 100644
index 0000000000..d3db63ec20
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/imageviewer/imageviewer.pro
@@ -0,0 +1,11 @@
+QT += widgets
+requires(qtConfig(filedialog))
+qtHaveModule(printsupport): QT += printsupport
+
+HEADERS = imageviewer.h
+SOURCES = imageviewer.cpp \
+ main.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/imageviewer
+INSTALLS += target
diff --git a/tests/manual/examples/widgets/widgets/imageviewer/main.cpp b/tests/manual/examples/widgets/widgets/imageviewer/main.cpp
new file mode 100644
index 0000000000..013f7d8689
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/imageviewer/main.cpp
@@ -0,0 +1,24 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QApplication>
+#include <QCommandLineParser>
+
+#include "imageviewer.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ QGuiApplication::setApplicationDisplayName(ImageViewer::tr("Image Viewer"));
+ QCommandLineParser commandLineParser;
+ commandLineParser.addHelpOption();
+ commandLineParser.addPositionalArgument(ImageViewer::tr("[file]"), ImageViewer::tr("Image file to open."));
+ commandLineParser.process(QCoreApplication::arguments());
+ ImageViewer imageViewer;
+ if (!commandLineParser.positionalArguments().isEmpty()
+ && !imageViewer.loadFile(commandLineParser.positionalArguments().constFirst())) {
+ return -1;
+ }
+ imageViewer.show();
+ return app.exec();
+}
diff --git a/tests/manual/examples/widgets/widgets/movie/CMakeLists.txt b/tests/manual/examples/widgets/widgets/movie/CMakeLists.txt
new file mode 100644
index 0000000000..49b766a11d
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/movie/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(movie LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/movie")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+
+qt_standard_project_setup()
+
+qt_add_executable(movie
+ main.cpp
+ movieplayer.cpp movieplayer.h
+)
+
+set_target_properties(movie PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(movie PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+)
+
+install(TARGETS movie
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/tests/manual/examples/widgets/widgets/movie/animation.gif b/tests/manual/examples/widgets/widgets/movie/animation.gif
new file mode 100644
index 0000000000..f674369efc
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/movie/animation.gif
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/movie/main.cpp b/tests/manual/examples/widgets/widgets/movie/main.cpp
new file mode 100644
index 0000000000..e5d4d3f040
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/movie/main.cpp
@@ -0,0 +1,15 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QApplication>
+
+#include "movieplayer.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ MoviePlayer player;
+ player.show();
+ player.show();
+ return app.exec();
+}
diff --git a/tests/manual/examples/widgets/widgets/movie/movie.pro b/tests/manual/examples/widgets/widgets/movie/movie.pro
new file mode 100644
index 0000000000..f9f89109e4
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/movie/movie.pro
@@ -0,0 +1,12 @@
+QT += widgets
+requires(qtConfig(filedialog))
+
+HEADERS = movieplayer.h
+SOURCES = main.cpp \
+ movieplayer.cpp
+
+EXAMPLE_FILES = animation.gif
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/movie
+INSTALLS += target
diff --git a/tests/manual/examples/widgets/widgets/movie/movieplayer.cpp b/tests/manual/examples/widgets/widgets/movie/movieplayer.cpp
new file mode 100644
index 0000000000..6f6ec14bb1
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/movie/movieplayer.cpp
@@ -0,0 +1,180 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "movieplayer.h"
+
+#include <QCheckBox>
+#include <QFileDialog>
+#include <QLabel>
+#include <QMovie>
+#include <QSlider>
+#include <QSpinBox>
+#include <QStyle>
+#include <QToolButton>
+#include <QVBoxLayout>
+
+MoviePlayer::MoviePlayer(QWidget *parent)
+ : QWidget(parent)
+{
+ movie = new QMovie(this);
+ movie->setCacheMode(QMovie::CacheAll);
+
+ movieLabel = new QLabel(tr("No movie loaded"));
+ movieLabel->setAlignment(Qt::AlignCenter);
+ movieLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
+ movieLabel->setBackgroundRole(QPalette::Dark);
+ movieLabel->setAutoFillBackground(true);
+
+ currentMovieDirectory = "movies";
+
+ createControls();
+ createButtons();
+
+ connect(movie, &QMovie::frameChanged, this, &MoviePlayer::updateFrameSlider);
+ connect(movie, &QMovie::stateChanged, this, &MoviePlayer::updateButtons);
+ connect(fitCheckBox, &QCheckBox::clicked, this, &MoviePlayer::fitToWindow);
+ connect(frameSlider, &QSlider::valueChanged, this, &MoviePlayer::goToFrame);
+ connect(speedSpinBox, &QSpinBox::valueChanged,
+ movie, &QMovie::setSpeed);
+
+ mainLayout = new QVBoxLayout;
+ mainLayout->addWidget(movieLabel);
+ mainLayout->addLayout(controlsLayout);
+ mainLayout->addLayout(buttonsLayout);
+ setLayout(mainLayout);
+
+ updateFrameSlider();
+ updateButtons();
+
+ setWindowTitle(tr("Movie Player"));
+ resize(400, 400);
+}
+
+void MoviePlayer::open()
+{
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open a Movie"),
+ currentMovieDirectory);
+ if (!fileName.isEmpty())
+ openFile(fileName);
+}
+
+void MoviePlayer::openFile(const QString &fileName)
+{
+ currentMovieDirectory = QFileInfo(fileName).path();
+
+ movie->stop();
+ movieLabel->setMovie(movie);
+ movie->setFileName(fileName);
+ movie->start();
+
+ updateFrameSlider();
+ updateButtons();
+}
+
+void MoviePlayer::goToFrame(int frame)
+{
+ movie->jumpToFrame(frame);
+}
+
+void MoviePlayer::fitToWindow()
+{
+ movieLabel->setScaledContents(fitCheckBox->isChecked());
+}
+
+void MoviePlayer::updateFrameSlider()
+{
+ bool hasFrames = (movie->currentFrameNumber() >= 0);
+
+ if (hasFrames) {
+ if (movie->frameCount() > 0) {
+ frameSlider->setMaximum(movie->frameCount() - 1);
+ } else {
+ if (movie->currentFrameNumber() > frameSlider->maximum())
+ frameSlider->setMaximum(movie->currentFrameNumber());
+ }
+ frameSlider->setValue(movie->currentFrameNumber());
+ } else {
+ frameSlider->setMaximum(0);
+ }
+ frameLabel->setEnabled(hasFrames);
+ frameSlider->setEnabled(hasFrames);
+}
+
+void MoviePlayer::updateButtons()
+{
+ playButton->setEnabled(movie->isValid() && movie->frameCount() != 1
+ && movie->state() == QMovie::NotRunning);
+ pauseButton->setEnabled(movie->state() != QMovie::NotRunning);
+ pauseButton->setChecked(movie->state() == QMovie::Paused);
+ stopButton->setEnabled(movie->state() != QMovie::NotRunning);
+}
+
+void MoviePlayer::createControls()
+{
+ fitCheckBox = new QCheckBox(tr("Fit to Window"));
+
+ frameLabel = new QLabel(tr("Current frame:"));
+
+ frameSlider = new QSlider(Qt::Horizontal);
+ frameSlider->setTickPosition(QSlider::TicksBelow);
+ frameSlider->setTickInterval(10);
+
+ speedLabel = new QLabel(tr("Speed:"));
+
+ speedSpinBox = new QSpinBox;
+ speedSpinBox->setRange(1, 9999);
+ speedSpinBox->setValue(100);
+ speedSpinBox->setSuffix(tr("%"));
+
+ controlsLayout = new QGridLayout;
+ controlsLayout->addWidget(fitCheckBox, 0, 0, 1, 2);
+ controlsLayout->addWidget(frameLabel, 1, 0);
+ controlsLayout->addWidget(frameSlider, 1, 1, 1, 2);
+ controlsLayout->addWidget(speedLabel, 2, 0);
+ controlsLayout->addWidget(speedSpinBox, 2, 1);
+}
+
+void MoviePlayer::createButtons()
+{
+ QSize iconSize(36, 36);
+
+ openButton = new QToolButton;
+ openButton->setIcon(style()->standardIcon(QStyle::SP_DialogOpenButton));
+ openButton->setIconSize(iconSize);
+ openButton->setToolTip(tr("Open File"));
+ connect(openButton, &QToolButton::clicked, this, &MoviePlayer::open);
+
+ playButton = new QToolButton;
+ playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
+ playButton->setIconSize(iconSize);
+ playButton->setToolTip(tr("Play"));
+ connect(playButton, &QToolButton::clicked, movie, &QMovie::start);
+
+ pauseButton = new QToolButton;
+ pauseButton->setCheckable(true);
+ pauseButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
+ pauseButton->setIconSize(iconSize);
+ pauseButton->setToolTip(tr("Pause"));
+ connect(pauseButton, &QToolButton::clicked, movie, &QMovie::setPaused);
+
+ stopButton = new QToolButton;
+ stopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop));
+ stopButton->setIconSize(iconSize);
+ stopButton->setToolTip(tr("Stop"));
+ connect(stopButton, &QToolButton::clicked, movie, &QMovie::stop);
+
+ quitButton = new QToolButton;
+ quitButton->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton));
+ quitButton->setIconSize(iconSize);
+ quitButton->setToolTip(tr("Quit"));
+ connect(quitButton, &QToolButton::clicked, this, &MoviePlayer::close);
+
+ buttonsLayout = new QHBoxLayout;
+ buttonsLayout->addStretch();
+ buttonsLayout->addWidget(openButton);
+ buttonsLayout->addWidget(playButton);
+ buttonsLayout->addWidget(pauseButton);
+ buttonsLayout->addWidget(stopButton);
+ buttonsLayout->addWidget(quitButton);
+ buttonsLayout->addStretch();
+}
diff --git a/tests/manual/examples/widgets/widgets/movie/movieplayer.h b/tests/manual/examples/widgets/widgets/movie/movieplayer.h
new file mode 100644
index 0000000000..362fd50535
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/movie/movieplayer.h
@@ -0,0 +1,59 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef MOVIEPLAYER_H
+#define MOVIEPLAYER_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QCheckBox;
+class QGridLayout;
+class QHBoxLayout;
+class QLabel;
+class QMovie;
+class QSlider;
+class QSpinBox;
+class QToolButton;
+class QVBoxLayout;
+QT_END_NAMESPACE
+
+class MoviePlayer : public QWidget
+{
+ Q_OBJECT
+
+public:
+ MoviePlayer(QWidget *parent = nullptr);
+ void openFile(const QString &fileName);
+
+private slots:
+ void open();
+ void goToFrame(int frame);
+ void fitToWindow();
+ void updateButtons();
+ void updateFrameSlider();
+
+private:
+ void createControls();
+ void createButtons();
+
+ QString currentMovieDirectory;
+ QLabel *movieLabel;
+ QMovie *movie;
+ QToolButton *openButton;
+ QToolButton *playButton;
+ QToolButton *pauseButton;
+ QToolButton *stopButton;
+ QToolButton *quitButton;
+ QCheckBox *fitCheckBox;
+ QSlider *frameSlider;
+ QSpinBox *speedSpinBox;
+ QLabel *frameLabel;
+ QLabel *speedLabel;
+
+ QGridLayout *controlsLayout;
+ QHBoxLayout *buttonsLayout;
+ QVBoxLayout *mainLayout;
+};
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/styles/CMakeLists.txt b/tests/manual/examples/widgets/widgets/styles/CMakeLists.txt
new file mode 100644
index 0000000000..ff1d64b9d9
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/styles/CMakeLists.txt
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(styles LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/styles")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+
+qt_standard_project_setup()
+
+qt_add_executable(styles
+ main.cpp
+ norwegianwoodstyle.cpp norwegianwoodstyle.h
+ widgetgallery.cpp widgetgallery.h
+)
+
+set_target_properties(styles PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(styles PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+)
+
+# Resources:
+set(styles_resource_files
+ "images/woodbackground.png"
+ "images/woodbutton.png"
+)
+
+qt_add_resources(styles "styles"
+ PREFIX
+ "/"
+ FILES
+ ${styles_resource_files}
+)
+
+install(TARGETS styles
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/tests/manual/examples/widgets/widgets/styles/images/woodbackground.png b/tests/manual/examples/widgets/widgets/styles/images/woodbackground.png
new file mode 100644
index 0000000000..8be3366bb4
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/styles/images/woodbackground.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/styles/images/woodbutton.png b/tests/manual/examples/widgets/widgets/styles/images/woodbutton.png
new file mode 100644
index 0000000000..adb59ef633
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/styles/images/woodbutton.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/styles/main.cpp b/tests/manual/examples/widgets/widgets/styles/main.cpp
new file mode 100644
index 0000000000..5c33895ea4
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/styles/main.cpp
@@ -0,0 +1,17 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QApplication>
+
+#include "norwegianwoodstyle.h"
+#include "widgetgallery.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication::setStyle(new NorwegianWoodStyle);
+
+ QApplication app(argc, argv);
+ WidgetGallery gallery;
+ gallery.show();
+ return app.exec();
+}
diff --git a/tests/manual/examples/widgets/widgets/styles/norwegianwoodstyle.cpp b/tests/manual/examples/widgets/widgets/styles/norwegianwoodstyle.cpp
new file mode 100644
index 0000000000..a8969dfd54
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/styles/norwegianwoodstyle.cpp
@@ -0,0 +1,310 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "norwegianwoodstyle.h"
+
+#include <QComboBox>
+#include <QPainter>
+#include <QPainterPath>
+#include <QPushButton>
+#include <QStyleFactory>
+
+NorwegianWoodStyle::NorwegianWoodStyle() :
+ QProxyStyle(QStyleFactory::create("windows"))
+{
+ setObjectName("NorwegianWood");
+}
+
+//! [0]
+QPalette NorwegianWoodStyle::standardPalette() const
+{
+ if (!m_standardPalette.isBrushSet(QPalette::Disabled, QPalette::Mid)) {
+ QColor brown(212, 140, 95);
+ QColor beige(236, 182, 120);
+ QColor slightlyOpaqueBlack(0, 0, 0, 63);
+
+ QImage backgroundImage(":/images/woodbackground.png");
+ QImage buttonImage(":/images/woodbutton.png");
+ QImage midImage = buttonImage.convertToFormat(QImage::Format_RGB32);
+
+ QPainter painter;
+ painter.begin(&midImage);
+ painter.setPen(Qt::NoPen);
+ painter.fillRect(midImage.rect(), slightlyOpaqueBlack);
+ painter.end();
+ //! [0]
+
+ //! [1]
+ QPalette palette(brown);
+
+ palette.setBrush(QPalette::BrightText, Qt::white);
+ palette.setBrush(QPalette::Base, beige);
+ palette.setBrush(QPalette::Highlight, Qt::darkGreen);
+ setTexture(palette, QPalette::Button, buttonImage);
+ setTexture(palette, QPalette::Mid, midImage);
+ setTexture(palette, QPalette::Window, backgroundImage);
+
+ QBrush brush = palette.window();
+ brush.setColor(brush.color().darker());
+
+ palette.setBrush(QPalette::Disabled, QPalette::WindowText, brush);
+ palette.setBrush(QPalette::Disabled, QPalette::Text, brush);
+ palette.setBrush(QPalette::Disabled, QPalette::ButtonText, brush);
+ palette.setBrush(QPalette::Disabled, QPalette::Base, brush);
+ palette.setBrush(QPalette::Disabled, QPalette::Button, brush);
+ palette.setBrush(QPalette::Disabled, QPalette::Mid, brush);
+
+ m_standardPalette = palette;
+ }
+
+ return m_standardPalette;
+}
+//! [1]
+
+//! [3]
+void NorwegianWoodStyle::polish(QWidget *widget)
+//! [3] //! [4]
+{
+ if (qobject_cast<QPushButton *>(widget)
+ || qobject_cast<QComboBox *>(widget))
+ widget->setAttribute(Qt::WA_Hover, true);
+}
+//! [4]
+
+//! [5]
+void NorwegianWoodStyle::unpolish(QWidget *widget)
+//! [5] //! [6]
+{
+ if (qobject_cast<QPushButton *>(widget)
+ || qobject_cast<QComboBox *>(widget))
+ widget->setAttribute(Qt::WA_Hover, false);
+}
+//! [6]
+
+//! [7]
+int NorwegianWoodStyle::pixelMetric(PixelMetric metric,
+//! [7] //! [8]
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ switch (metric) {
+ case PM_ComboBoxFrameWidth:
+ return 8;
+ case PM_ScrollBarExtent:
+ return QProxyStyle::pixelMetric(metric, option, widget) + 4;
+ default:
+ return QProxyStyle::pixelMetric(metric, option, widget);
+ }
+}
+//! [8]
+
+//! [9]
+int NorwegianWoodStyle::styleHint(StyleHint hint, const QStyleOption *option,
+//! [9] //! [10]
+ const QWidget *widget,
+ QStyleHintReturn *returnData) const
+{
+ switch (hint) {
+ case SH_DitherDisabledText:
+ return int(false);
+ case SH_EtchDisabledText:
+ return int(true);
+ default:
+ return QProxyStyle::styleHint(hint, option, widget, returnData);
+ }
+}
+//! [10]
+
+//! [11]
+void NorwegianWoodStyle::drawPrimitive(PrimitiveElement element,
+//! [11] //! [12]
+ const QStyleOption *option,
+ QPainter *painter,
+ const QWidget *widget) const
+{
+ switch (element) {
+ case PE_PanelButtonCommand:
+ {
+ int delta = (option->state & State_MouseOver) ? 64 : 0;
+ QColor slightlyOpaqueBlack(0, 0, 0, 63);
+ QColor semiTransparentWhite(255, 255, 255, 127 + delta);
+ QColor semiTransparentBlack(0, 0, 0, 127 - delta);
+
+ int x, y, width, height;
+ option->rect.getRect(&x, &y, &width, &height);
+//! [12]
+
+//! [13]
+ QPainterPath roundRect = roundRectPath(option->rect);
+//! [13] //! [14]
+ int radius = qMin(width, height) / 2;
+//! [14]
+
+//! [15]
+ QBrush brush;
+//! [15] //! [16]
+ bool darker;
+
+ const QStyleOptionButton *buttonOption =
+ qstyleoption_cast<const QStyleOptionButton *>(option);
+ if (buttonOption
+ && (buttonOption->features & QStyleOptionButton::Flat)) {
+ brush = option->palette.window();
+ darker = (option->state & (State_Sunken | State_On));
+ } else {
+ if (option->state & (State_Sunken | State_On)) {
+ brush = option->palette.mid();
+ darker = !(option->state & State_Sunken);
+ } else {
+ brush = option->palette.button();
+ darker = false;
+//! [16] //! [17]
+ }
+//! [17] //! [18]
+ }
+//! [18]
+
+//! [19]
+ painter->save();
+//! [19] //! [20]
+ painter->setRenderHint(QPainter::Antialiasing, true);
+//! [20] //! [21]
+ painter->fillPath(roundRect, brush);
+//! [21] //! [22]
+ if (darker)
+//! [22] //! [23]
+ painter->fillPath(roundRect, slightlyOpaqueBlack);
+//! [23]
+
+//! [24]
+ int penWidth;
+//! [24] //! [25]
+ if (radius < 10)
+ penWidth = 3;
+ else if (radius < 20)
+ penWidth = 5;
+ else
+ penWidth = 7;
+
+ QPen topPen(semiTransparentWhite, penWidth);
+ QPen bottomPen(semiTransparentBlack, penWidth);
+
+ if (option->state & (State_Sunken | State_On))
+ qSwap(topPen, bottomPen);
+//! [25]
+
+//! [26]
+ int x1 = x;
+ int x2 = x + radius;
+ int x3 = x + width - radius;
+ int x4 = x + width;
+
+ if (option->direction == Qt::RightToLeft) {
+ qSwap(x1, x4);
+ qSwap(x2, x3);
+ }
+
+ QPolygon topHalf;
+ topHalf << QPoint(x1, y)
+ << QPoint(x4, y)
+ << QPoint(x3, y + radius)
+ << QPoint(x2, y + height - radius)
+ << QPoint(x1, y + height);
+
+ painter->setClipPath(roundRect);
+ painter->setClipRegion(topHalf, Qt::IntersectClip);
+ painter->setPen(topPen);
+ painter->drawPath(roundRect);
+//! [26] //! [32]
+
+ QPolygon bottomHalf = topHalf;
+ bottomHalf[0] = QPoint(x4, y + height);
+
+ painter->setClipPath(roundRect);
+ painter->setClipRegion(bottomHalf, Qt::IntersectClip);
+ painter->setPen(bottomPen);
+ painter->drawPath(roundRect);
+
+ painter->setPen(option->palette.windowText().color());
+ painter->setClipping(false);
+ painter->drawPath(roundRect);
+
+ painter->restore();
+ }
+ break;
+//! [32] //! [33]
+ default:
+//! [33] //! [34]
+ QProxyStyle::drawPrimitive(element, option, painter, widget);
+ }
+}
+//! [34]
+
+//! [35]
+void NorwegianWoodStyle::drawControl(ControlElement element,
+//! [35] //! [36]
+ const QStyleOption *option,
+ QPainter *painter,
+ const QWidget *widget) const
+{
+ switch (element) {
+ case CE_PushButtonLabel:
+ {
+ QStyleOptionButton myButtonOption;
+ const QStyleOptionButton *buttonOption =
+ qstyleoption_cast<const QStyleOptionButton *>(option);
+ if (buttonOption) {
+ myButtonOption = *buttonOption;
+ if (myButtonOption.palette.currentColorGroup()
+ != QPalette::Disabled) {
+ if (myButtonOption.state & (State_Sunken | State_On)) {
+ myButtonOption.palette.setBrush(QPalette::ButtonText,
+ myButtonOption.palette.brightText());
+ }
+ }
+ }
+ QProxyStyle::drawControl(element, &myButtonOption, painter, widget);
+ }
+ break;
+ default:
+ QProxyStyle::drawControl(element, option, painter, widget);
+ }
+}
+//! [36]
+
+//! [37]
+void NorwegianWoodStyle::setTexture(QPalette &palette, QPalette::ColorRole role,
+//! [37] //! [38]
+ const QImage &image)
+{
+ for (int i = 0; i < QPalette::NColorGroups; ++i) {
+ QBrush brush(image);
+ brush.setColor(palette.brush(QPalette::ColorGroup(i), role).color());
+ palette.setBrush(QPalette::ColorGroup(i), role, brush);
+ }
+}
+//! [38]
+
+//! [39]
+QPainterPath NorwegianWoodStyle::roundRectPath(const QRect &rect)
+//! [39] //! [40]
+{
+ int radius = qMin(rect.width(), rect.height()) / 2;
+ int diam = 2 * radius;
+
+ int x1, y1, x2, y2;
+ rect.getCoords(&x1, &y1, &x2, &y2);
+
+ QPainterPath path;
+ path.moveTo(x2, y1 + radius);
+ path.arcTo(QRect(x2 - diam, y1, diam, diam), 0.0, +90.0);
+ path.lineTo(x1 + radius, y1);
+ path.arcTo(QRect(x1, y1, diam, diam), 90.0, +90.0);
+ path.lineTo(x1, y2 - radius);
+ path.arcTo(QRect(x1, y2 - diam, diam, diam), 180.0, +90.0);
+ path.lineTo(x1 + radius, y2);
+ path.arcTo(QRect(x2 - diam, y2 - diam, diam, diam), 270.0, +90.0);
+ path.closeSubpath();
+ return path;
+}
+//! [40]
diff --git a/tests/manual/examples/widgets/widgets/styles/norwegianwoodstyle.h b/tests/manual/examples/widgets/widgets/styles/norwegianwoodstyle.h
new file mode 100644
index 0000000000..5af2171f35
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/styles/norwegianwoodstyle.h
@@ -0,0 +1,43 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef NORWEGIANWOODSTYLE_H
+#define NORWEGIANWOODSTYLE_H
+
+#include <QProxyStyle>
+#include <QPalette>
+
+QT_BEGIN_NAMESPACE
+class QPainterPath;
+QT_END_NAMESPACE
+
+//! [0]
+class NorwegianWoodStyle : public QProxyStyle
+{
+ Q_OBJECT
+
+public:
+ NorwegianWoodStyle();
+
+ QPalette standardPalette() const override;
+
+ void polish(QWidget *widget) override;
+ void unpolish(QWidget *widget) override;
+ int pixelMetric(PixelMetric metric, const QStyleOption *option,
+ const QWidget *widget) const override;
+ int styleHint(StyleHint hint, const QStyleOption *option,
+ const QWidget *widget, QStyleHintReturn *returnData) const override;
+ void drawPrimitive(PrimitiveElement element, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const override;
+ void drawControl(ControlElement control, const QStyleOption *option,
+ QPainter *painter, const QWidget *widget) const override;
+
+private:
+ static void setTexture(QPalette &palette, QPalette::ColorRole role,
+ const QImage &image);
+ static QPainterPath roundRectPath(const QRect &rect);
+ mutable QPalette m_standardPalette;
+};
+//! [0]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/styles/styles.pro b/tests/manual/examples/widgets/widgets/styles/styles.pro
new file mode 100644
index 0000000000..87dee7e04c
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/styles/styles.pro
@@ -0,0 +1,13 @@
+QT += widgets
+requires(qtConfig(combobox))
+
+HEADERS = norwegianwoodstyle.h \
+ widgetgallery.h
+SOURCES = main.cpp \
+ norwegianwoodstyle.cpp \
+ widgetgallery.cpp
+RESOURCES = styles.qrc
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/styles
+INSTALLS += target
diff --git a/tests/manual/examples/widgets/widgets/styles/styles.qrc b/tests/manual/examples/widgets/widgets/styles/styles.qrc
new file mode 100644
index 0000000000..4fdad8d914
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/styles/styles.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>images/woodbutton.png</file>
+ <file>images/woodbackground.png</file>
+</qresource>
+</RCC>
diff --git a/tests/manual/examples/widgets/widgets/styles/widgetgallery.cpp b/tests/manual/examples/widgets/widgets/styles/widgetgallery.cpp
new file mode 100644
index 0000000000..83cb99a52c
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/styles/widgetgallery.cpp
@@ -0,0 +1,277 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "widgetgallery.h"
+#include "norwegianwoodstyle.h"
+
+#include <QApplication>
+#include <QCheckBox>
+#include <QComboBox>
+#include <QDateTimeEdit>
+#include <QDial>
+#include <QGridLayout>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QProgressBar>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QScrollBar>
+#include <QSpinBox>
+#include <QStyle>
+#include <QStyleFactory>
+#include <QTableWidget>
+#include <QTextEdit>
+#include <QTimer>
+
+//! [0]
+WidgetGallery::WidgetGallery(QWidget *parent)
+ : QDialog(parent)
+{
+ styleComboBox = new QComboBox;
+ const QString defaultStyleName = QApplication::style()->objectName();
+ QStringList styleNames = QStyleFactory::keys();
+ styleNames.append("NorwegianWood");
+ for (int i = 1, size = styleNames.size(); i < size; ++i) {
+ if (defaultStyleName.compare(styleNames.at(i), Qt::CaseInsensitive) == 0) {
+ styleNames.swapItemsAt(0, i);
+ break;
+ }
+ }
+ styleComboBox->addItems(styleNames);
+
+ styleLabel = new QLabel(tr("&Style:"));
+ styleLabel->setBuddy(styleComboBox);
+
+ useStylePaletteCheckBox = new QCheckBox(tr("&Use style's standard palette"));
+ useStylePaletteCheckBox->setChecked(true);
+
+ disableWidgetsCheckBox = new QCheckBox(tr("&Disable widgets"));
+
+ createTopLeftGroupBox();
+ createTopRightGroupBox();
+ createBottomLeftTabWidget();
+ createBottomRightGroupBox();
+ createProgressBar();
+//! [0]
+
+//! [1]
+ connect(styleComboBox, &QComboBox::textActivated,
+//! [1] //! [2]
+ this, &WidgetGallery::changeStyle);
+ connect(useStylePaletteCheckBox, &QCheckBox::toggled,
+ this, &WidgetGallery::changePalette);
+ connect(disableWidgetsCheckBox, &QCheckBox::toggled,
+ topLeftGroupBox, &QGroupBox::setDisabled);
+ connect(disableWidgetsCheckBox, &QCheckBox::toggled,
+ topRightGroupBox, &QGroupBox::setDisabled);
+ connect(disableWidgetsCheckBox, &QCheckBox::toggled,
+ bottomLeftTabWidget, &QGroupBox::setDisabled);
+ connect(disableWidgetsCheckBox, &QCheckBox::toggled,
+ bottomRightGroupBox, &QGroupBox::setDisabled);
+//! [2]
+
+//! [3]
+ QHBoxLayout *topLayout = new QHBoxLayout;
+//! [3] //! [4]
+ topLayout->addWidget(styleLabel);
+ topLayout->addWidget(styleComboBox);
+ topLayout->addStretch(1);
+ topLayout->addWidget(useStylePaletteCheckBox);
+ topLayout->addWidget(disableWidgetsCheckBox);
+
+ QGridLayout *mainLayout = new QGridLayout;
+ mainLayout->addLayout(topLayout, 0, 0, 1, 2);
+ mainLayout->addWidget(topLeftGroupBox, 1, 0);
+ mainLayout->addWidget(topRightGroupBox, 1, 1);
+ mainLayout->addWidget(bottomLeftTabWidget, 2, 0);
+ mainLayout->addWidget(bottomRightGroupBox, 2, 1);
+ mainLayout->addWidget(progressBar, 3, 0, 1, 2);
+ mainLayout->setRowStretch(1, 1);
+ mainLayout->setRowStretch(2, 1);
+ mainLayout->setColumnStretch(0, 1);
+ mainLayout->setColumnStretch(1, 1);
+ setLayout(mainLayout);
+
+ setWindowTitle(tr("Styles"));
+ styleChanged();
+}
+//! [4]
+
+//! [5]
+void WidgetGallery::changeStyle(const QString &styleName)
+//! [5] //! [6]
+{
+ if (styleName == "NorwegianWood")
+ QApplication::setStyle(new NorwegianWoodStyle);
+ else
+ QApplication::setStyle(QStyleFactory::create(styleName));
+}
+//! [6]
+
+//! [7]
+void WidgetGallery::changePalette()
+//! [7] //! [8]
+{
+ QApplication::setPalette(useStylePaletteCheckBox->isChecked() ?
+ QApplication::style()->standardPalette() : QPalette());
+}
+//! [8]
+
+void WidgetGallery::changeEvent(QEvent *event)
+{
+ if (event->type() == QEvent::StyleChange)
+ styleChanged();
+}
+
+void WidgetGallery::styleChanged()
+{
+ auto styleName = QApplication::style()->objectName();
+ for (int i = 0; i < styleComboBox->count(); ++i) {
+ if (QString::compare(styleComboBox->itemText(i), styleName, Qt::CaseInsensitive) == 0) {
+ styleComboBox->setCurrentIndex(i);
+ break;
+ }
+ }
+
+ changePalette();
+}
+
+//! [9]
+void WidgetGallery::advanceProgressBar()
+//! [9] //! [10]
+{
+ int curVal = progressBar->value();
+ int maxVal = progressBar->maximum();
+ progressBar->setValue(curVal + (maxVal - curVal) / 100);
+}
+//! [10]
+
+//! [11]
+void WidgetGallery::createTopLeftGroupBox()
+//! [11] //! [12]
+{
+ topLeftGroupBox = new QGroupBox(tr("Group 1"));
+
+ radioButton1 = new QRadioButton(tr("Radio button 1"));
+ radioButton2 = new QRadioButton(tr("Radio button 2"));
+ radioButton3 = new QRadioButton(tr("Radio button 3"));
+ radioButton1->setChecked(true);
+
+ checkBox = new QCheckBox(tr("Tri-state check box"));
+ checkBox->setTristate(true);
+ checkBox->setCheckState(Qt::PartiallyChecked);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(radioButton1);
+ layout->addWidget(radioButton2);
+ layout->addWidget(radioButton3);
+ layout->addWidget(checkBox);
+ layout->addStretch(1);
+ topLeftGroupBox->setLayout(layout);
+}
+//! [12]
+
+void WidgetGallery::createTopRightGroupBox()
+{
+ topRightGroupBox = new QGroupBox(tr("Group 2"));
+
+ defaultPushButton = new QPushButton(tr("Default Push Button"));
+ defaultPushButton->setDefault(true);
+
+ togglePushButton = new QPushButton(tr("Toggle Push Button"));
+ togglePushButton->setCheckable(true);
+ togglePushButton->setChecked(true);
+
+ flatPushButton = new QPushButton(tr("Flat Push Button"));
+ flatPushButton->setFlat(true);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->addWidget(defaultPushButton);
+ layout->addWidget(togglePushButton);
+ layout->addWidget(flatPushButton);
+ layout->addStretch(1);
+ topRightGroupBox->setLayout(layout);
+}
+
+void WidgetGallery::createBottomLeftTabWidget()
+{
+ bottomLeftTabWidget = new QTabWidget;
+ bottomLeftTabWidget->setSizePolicy(QSizePolicy::Preferred,
+ QSizePolicy::Ignored);
+
+ QWidget *tab1 = new QWidget;
+ tableWidget = new QTableWidget(10, 10);
+
+ QHBoxLayout *tab1hbox = new QHBoxLayout;
+ tab1hbox->setContentsMargins(5,5, 5, 5);
+ tab1hbox->addWidget(tableWidget);
+ tab1->setLayout(tab1hbox);
+
+ QWidget *tab2 = new QWidget;
+ textEdit = new QTextEdit;
+
+ textEdit->setPlainText(tr("Twinkle, twinkle, little star,\n"
+ "How I wonder what you are.\n"
+ "Up above the world so high,\n"
+ "Like a diamond in the sky.\n"
+ "Twinkle, twinkle, little star,\n"
+ "How I wonder what you are!\n"));
+
+ QHBoxLayout *tab2hbox = new QHBoxLayout;
+ tab2hbox->setContentsMargins(5, 5, 5, 5);
+ tab2hbox->addWidget(textEdit);
+ tab2->setLayout(tab2hbox);
+
+ bottomLeftTabWidget->addTab(tab1, tr("&Table"));
+ bottomLeftTabWidget->addTab(tab2, tr("Text &Edit"));
+}
+
+void WidgetGallery::createBottomRightGroupBox()
+{
+ bottomRightGroupBox = new QGroupBox(tr("Group 3"));
+ bottomRightGroupBox->setCheckable(true);
+ bottomRightGroupBox->setChecked(true);
+
+ lineEdit = new QLineEdit("s3cRe7");
+ lineEdit->setEchoMode(QLineEdit::Password);
+
+ spinBox = new QSpinBox(bottomRightGroupBox);
+ spinBox->setValue(50);
+
+ dateTimeEdit = new QDateTimeEdit(bottomRightGroupBox);
+ dateTimeEdit->setDateTime(QDateTime::currentDateTime());
+
+ slider = new QSlider(Qt::Horizontal, bottomRightGroupBox);
+ slider->setValue(40);
+
+ scrollBar = new QScrollBar(Qt::Horizontal, bottomRightGroupBox);
+ scrollBar->setValue(60);
+
+ dial = new QDial(bottomRightGroupBox);
+ dial->setValue(30);
+ dial->setNotchesVisible(true);
+
+ QGridLayout *layout = new QGridLayout;
+ layout->addWidget(lineEdit, 0, 0, 1, 2);
+ layout->addWidget(spinBox, 1, 0, 1, 2);
+ layout->addWidget(dateTimeEdit, 2, 0, 1, 2);
+ layout->addWidget(slider, 3, 0);
+ layout->addWidget(scrollBar, 4, 0);
+ layout->addWidget(dial, 3, 1, 2, 1);
+ layout->setRowStretch(5, 1);
+ bottomRightGroupBox->setLayout(layout);
+}
+
+//! [13]
+void WidgetGallery::createProgressBar()
+{
+ progressBar = new QProgressBar;
+ progressBar->setRange(0, 10000);
+ progressBar->setValue(0);
+
+ QTimer *timer = new QTimer(this);
+ connect(timer, &QTimer::timeout, this, &WidgetGallery::advanceProgressBar);
+ timer->start(1000);
+}
+//! [13]
diff --git a/tests/manual/examples/widgets/widgets/styles/widgetgallery.h b/tests/manual/examples/widgets/widgets/styles/widgetgallery.h
new file mode 100644
index 0000000000..f4c43e7b4f
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/styles/widgetgallery.h
@@ -0,0 +1,86 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef WIDGETGALLERY_H
+#define WIDGETGALLERY_H
+
+#include <QDialog>
+
+QT_BEGIN_NAMESPACE
+class QCheckBox;
+class QComboBox;
+class QDateTimeEdit;
+class QDial;
+class QGroupBox;
+class QLabel;
+class QLineEdit;
+class QProgressBar;
+class QPushButton;
+class QRadioButton;
+class QScrollBar;
+class QSlider;
+class QSpinBox;
+class QTabWidget;
+class QTableWidget;
+class QTextEdit;
+QT_END_NAMESPACE
+
+//! [0]
+class WidgetGallery : public QDialog
+{
+ Q_OBJECT
+
+public:
+ WidgetGallery(QWidget *parent = nullptr);
+
+protected:
+ void changeEvent(QEvent *) override;
+
+private slots:
+ void changeStyle(const QString &styleName);
+ void styleChanged();
+ void changePalette();
+ void advanceProgressBar();
+
+private:
+ void createTopLeftGroupBox();
+ void createTopRightGroupBox();
+ void createBottomLeftTabWidget();
+ void createBottomRightGroupBox();
+ void createProgressBar();
+
+ QLabel *styleLabel;
+ QComboBox *styleComboBox;
+ QCheckBox *useStylePaletteCheckBox;
+ QCheckBox *disableWidgetsCheckBox;
+//! [0]
+
+ QGroupBox *topLeftGroupBox;
+ QRadioButton *radioButton1;
+ QRadioButton *radioButton2;
+ QRadioButton *radioButton3;
+ QCheckBox *checkBox;
+
+ QGroupBox *topRightGroupBox;
+ QPushButton *defaultPushButton;
+ QPushButton *togglePushButton;
+ QPushButton *flatPushButton;
+
+ QTabWidget *bottomLeftTabWidget;
+ QTableWidget *tableWidget;
+ QTextEdit *textEdit;
+
+ QGroupBox *bottomRightGroupBox;
+ QLineEdit *lineEdit;
+ QSpinBox *spinBox;
+ QDateTimeEdit *dateTimeEdit;
+ QSlider *slider;
+ QScrollBar *scrollBar;
+ QDial *dial;
+
+ QProgressBar *progressBar;
+//! [1]
+};
+//! [1]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/CMakeLists.txt b/tests/manual/examples/widgets/widgets/stylesheet/CMakeLists.txt
new file mode 100644
index 0000000000..7937f6076f
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/CMakeLists.txt
@@ -0,0 +1,84 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(stylesheet LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/stylesheet")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+
+qt_standard_project_setup()
+
+qt_add_executable(stylesheet
+ main.cpp
+ mainwindow.cpp mainwindow.h mainwindow.ui
+ stylesheeteditor.cpp stylesheeteditor.h stylesheeteditor.ui
+)
+
+set_target_properties(stylesheet PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(stylesheet PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+)
+
+# Resources:
+set(stylesheet_resource_files
+ "images/checkbox_checked.png"
+ "images/checkbox_checked_hover.png"
+ "images/checkbox_checked_pressed.png"
+ "images/checkbox_unchecked.png"
+ "images/checkbox_unchecked_hover.png"
+ "images/checkbox_unchecked_pressed.png"
+ "images/down_arrow.png"
+ "images/down_arrow_disabled.png"
+ "images/frame.png"
+ "images/pagefold.png"
+ "images/pushbutton.png"
+ "images/pushbutton_hover.png"
+ "images/pushbutton_pressed.png"
+ "images/radiobutton_checked.png"
+ "images/radiobutton_checked_hover.png"
+ "images/radiobutton_checked_pressed.png"
+ "images/radiobutton_unchecked.png"
+ "images/radiobutton_unchecked_hover.png"
+ "images/radiobutton_unchecked_pressed.png"
+ "images/sizegrip.png"
+ "images/spindown.png"
+ "images/spindown_hover.png"
+ "images/spindown_off.png"
+ "images/spindown_pressed.png"
+ "images/spinup.png"
+ "images/spinup_hover.png"
+ "images/spinup_off.png"
+ "images/spinup_pressed.png"
+ "images/up_arrow.png"
+ "images/up_arrow_disabled.png"
+ "layouts/default.ui"
+ "layouts/pagefold.ui"
+ "qss/coffee.qss"
+ "qss/default.qss"
+ "qss/pagefold.qss"
+)
+
+qt_add_resources(stylesheet "stylesheet"
+ PREFIX
+ "/"
+ FILES
+ ${stylesheet_resource_files}
+)
+
+install(TARGETS stylesheet
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked.png b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked.png
new file mode 100644
index 0000000000..cbf06f6513
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked_hover.png b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked_hover.png
new file mode 100644
index 0000000000..fb4d4d3fdb
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked_hover.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked_pressed.png b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked_pressed.png
new file mode 100644
index 0000000000..852fcc0306
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_checked_pressed.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked.png b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked.png
new file mode 100644
index 0000000000..5f5465582a
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked_hover.png b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked_hover.png
new file mode 100644
index 0000000000..687364497e
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked_hover.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked_pressed.png b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked_pressed.png
new file mode 100644
index 0000000000..6a768c44de
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/checkbox_unchecked_pressed.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/down_arrow.png b/tests/manual/examples/widgets/widgets/stylesheet/images/down_arrow.png
new file mode 100644
index 0000000000..85004aeaf6
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/down_arrow.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/down_arrow_disabled.png b/tests/manual/examples/widgets/widgets/stylesheet/images/down_arrow_disabled.png
new file mode 100644
index 0000000000..d9eefed4c8
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/down_arrow_disabled.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/frame.png b/tests/manual/examples/widgets/widgets/stylesheet/images/frame.png
new file mode 100644
index 0000000000..05a600502e
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/frame.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/pagefold.png b/tests/manual/examples/widgets/widgets/stylesheet/images/pagefold.png
new file mode 100644
index 0000000000..69be8f2a38
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/pagefold.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton.png b/tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton.png
new file mode 100644
index 0000000000..c7529ba02d
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton_hover.png b/tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton_hover.png
new file mode 100644
index 0000000000..af0ef9d561
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton_hover.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton_pressed.png b/tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton_pressed.png
new file mode 100644
index 0000000000..f7381f752a
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/pushbutton_pressed.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked.png b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked.png
new file mode 100644
index 0000000000..8ab9157578
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked_hover.png b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked_hover.png
new file mode 100644
index 0000000000..d68cb009a7
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked_hover.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked_pressed.png b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked_pressed.png
new file mode 100644
index 0000000000..e3cd5a59e4
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_checked_pressed.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked.png b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked.png
new file mode 100644
index 0000000000..321a9a1558
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked_hover.png b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked_hover.png
new file mode 100644
index 0000000000..666a3b0bdd
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked_hover.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked_pressed.png b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked_pressed.png
new file mode 100644
index 0000000000..c4b0567aa9
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/radiobutton_unchecked_pressed.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/sizegrip.png b/tests/manual/examples/widgets/widgets/stylesheet/images/sizegrip.png
new file mode 100644
index 0000000000..350583aaac
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/sizegrip.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/spindown.png b/tests/manual/examples/widgets/widgets/stylesheet/images/spindown.png
new file mode 100644
index 0000000000..7ff3c64926
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/spindown.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/spindown_hover.png b/tests/manual/examples/widgets/widgets/stylesheet/images/spindown_hover.png
new file mode 100644
index 0000000000..1486c4dfe4
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/spindown_hover.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/spindown_off.png b/tests/manual/examples/widgets/widgets/stylesheet/images/spindown_off.png
new file mode 100644
index 0000000000..a90ab3f038
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/spindown_off.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/spindown_pressed.png b/tests/manual/examples/widgets/widgets/stylesheet/images/spindown_pressed.png
new file mode 100644
index 0000000000..f6271cbde2
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/spindown_pressed.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/spinup.png b/tests/manual/examples/widgets/widgets/stylesheet/images/spinup.png
new file mode 100644
index 0000000000..1069dd00df
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/spinup.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/spinup_hover.png b/tests/manual/examples/widgets/widgets/stylesheet/images/spinup_hover.png
new file mode 100644
index 0000000000..884c8d77c5
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/spinup_hover.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/spinup_off.png b/tests/manual/examples/widgets/widgets/stylesheet/images/spinup_off.png
new file mode 100644
index 0000000000..02dad1fb29
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/spinup_off.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/spinup_pressed.png b/tests/manual/examples/widgets/widgets/stylesheet/images/spinup_pressed.png
new file mode 100644
index 0000000000..b1843e2a1f
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/spinup_pressed.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/up_arrow.png b/tests/manual/examples/widgets/widgets/stylesheet/images/up_arrow.png
new file mode 100644
index 0000000000..e7f7ddb3a6
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/up_arrow.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/images/up_arrow_disabled.png b/tests/manual/examples/widgets/widgets/stylesheet/images/up_arrow_disabled.png
new file mode 100644
index 0000000000..4d2c27770f
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/images/up_arrow_disabled.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/layouts/default.ui b/tests/manual/examples/widgets/widgets/stylesheet/layouts/default.ui
new file mode 100644
index 0000000000..431a40956e
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/layouts/default.ui
@@ -0,0 +1,329 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>388</width>
+ <height>413</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="nameLabel" >
+ <property name="text" >
+ <string>&amp;Name:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>nameCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="3" >
+ <widget class="QComboBox" name="nameCombo" >
+ <property name="toolTip" >
+ <string>Specify your name</string>
+ </property>
+ <property name="editable" >
+ <bool>true</bool>
+ </property>
+ <property name="currentIndex" >
+ <number>-1</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Girish</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Jasmin</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Simon</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Zack</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QRadioButton" name="femaleRadioButton" >
+ <property name="toolTip" >
+ <string>Check this if you are female</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Female</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="4" >
+ <widget class="QCheckBox" name="agreeCheckBox" >
+ <property name="toolTip" >
+ <string>Please read the license before checking this</string>
+ </property>
+ <property name="text" >
+ <string>I &amp;accept the terms and conditions</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QRadioButton" name="maleRadioButton" >
+ <property name="toolTip" >
+ <string>Check this if you are male</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Male</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="genderLabel" >
+ <property name="text" >
+ <string>Gender:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="3" >
+ <widget class="QSpinBox" name="ageSpinBox" >
+ <property name="toolTip" >
+ <string>Specify your age</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify your age here</string>
+ </property>
+ <property name="minimum" >
+ <number>12</number>
+ </property>
+ <property name="value" >
+ <number>22</number>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="2" colspan="2" >
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="ageLabel" >
+ <property name="text" >
+ <string>&amp;Age:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>ageSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="passwordLabel" >
+ <property name="text" >
+ <string>&amp;Password:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>passwordEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="3" >
+ <widget class="QLineEdit" name="passwordEdit" >
+ <property name="toolTip" >
+ <string>Specify your password</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify your password here</string>
+ </property>
+ <property name="text" >
+ <string>Password</string>
+ </property>
+ <property name="echoMode" >
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Profession</string>
+ </property>
+ <property name="buddy" >
+ <cstring>professionList</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="countryLabel" >
+ <property name="text" >
+ <string>&amp;Country</string>
+ </property>
+ <property name="buddy" >
+ <cstring>professionList</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" colspan="3" >
+ <widget class="QListWidget" name="professionList" >
+ <property name="toolTip" >
+ <string>Select your profession</string>
+ </property>
+ <property name="statusTip" >
+ <string>Select your profession</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Select your profession</string>
+ </property>
+ <property name="currentRow" >
+ <number>1</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Developer</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Student</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Fisherman</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="1" colspan="3" >
+ <widget class="QComboBox" name="countryCombo" >
+ <property name="toolTip" >
+ <string>Specify your country</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify your country here</string>
+ </property>
+ <property name="currentIndex" >
+ <number>2</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Germany</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>India</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Norway</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>United States Of America</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>United Kingdom</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>388</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menu_File" >
+ <property name="title" >
+ <string>&amp;File</string>
+ </property>
+ <addaction name="editStyleAction" />
+ <addaction name="separator" />
+ <addaction name="exitAction" />
+ </widget>
+ <widget class="QMenu" name="menu_Help" >
+ <property name="title" >
+ <string>&amp;Help</string>
+ </property>
+ <addaction name="aboutAction" />
+ <addaction name="separator" />
+ <addaction name="aboutQtAction" />
+ </widget>
+ <addaction name="menu_File" />
+ <addaction name="menu_Help" />
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ <action name="exitAction" >
+ <property name="text" >
+ <string>&amp;Exit</string>
+ </property>
+ </action>
+ <action name="aboutQtAction" >
+ <property name="text" >
+ <string>About Qt</string>
+ </property>
+ </action>
+ <action name="editStyleAction" >
+ <property name="text" >
+ <string>Edit &amp;Style</string>
+ </property>
+ </action>
+ <action name="aboutAction" >
+ <property name="text" >
+ <string>About</string>
+ </property>
+ </action>
+ </widget>
+ <tabstops>
+ <tabstop>maleRadioButton</tabstop>
+ <tabstop>femaleRadioButton</tabstop>
+ <tabstop>ageSpinBox</tabstop>
+ <tabstop>passwordEdit</tabstop>
+ <tabstop>professionList</tabstop>
+ <tabstop>agreeCheckBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/layouts/pagefold.ui b/tests/manual/examples/widgets/widgets/stylesheet/layouts/pagefold.ui
new file mode 100644
index 0000000000..7ae313c331
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/layouts/pagefold.ui
@@ -0,0 +1,349 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>392</width>
+ <height>412</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>MainWindow</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="mainFrame" >
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="1" colspan="3" >
+ <widget class="QComboBox" name="nameCombo" >
+ <property name="toolTip" >
+ <string>Specify your name</string>
+ </property>
+ <property name="editable" >
+ <bool>true</bool>
+ </property>
+ <property name="currentIndex" >
+ <number>-1</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Girish</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Jasmin</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Simon</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Zack</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QRadioButton" name="femaleRadioButton" >
+ <property name="styleSheet" >
+ <string>Check this if you are female</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Female</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="genderLabel" >
+ <property name="text" >
+ <string>Gender:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="ageLabel" >
+ <property name="text" >
+ <string>&amp;Age:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>ageSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QRadioButton" name="maleRadioButton" >
+ <property name="toolTip" >
+ <string>Check this if you are male</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Male</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="nameLabel" >
+ <property name="text" >
+ <string>&amp;Name:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>nameCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="passwordLabel" >
+ <property name="text" >
+ <string>&amp;Password:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>passwordEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="3" >
+ <widget class="QSpinBox" name="ageSpinBox" >
+ <property name="toolTip" >
+ <string>Specify your age</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify your age</string>
+ </property>
+ <property name="minimum" >
+ <number>12</number>
+ </property>
+ <property name="value" >
+ <number>22</number>
+ </property>
+ </widget>
+ </item>
+ <item row="7" column="2" colspan="2" >
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="4" >
+ <widget class="QCheckBox" name="agreeCheckBox" >
+ <property name="toolTip" >
+ <string>Please read the LICENSE file before checking</string>
+ </property>
+ <property name="text" >
+ <string>I &amp;accept the terms and &amp;conditions</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="3" >
+ <widget class="QLineEdit" name="passwordEdit" >
+ <property name="toolTip" >
+ <string>Specify your password</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify your password</string>
+ </property>
+ <property name="text" >
+ <string>Password</string>
+ </property>
+ <property name="echoMode" >
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" colspan="3" >
+ <widget class="QListWidget" name="professionList" >
+ <property name="toolTip" >
+ <string>Select your profession</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify your name here</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Specify your name here</string>
+ </property>
+ <property name="currentRow" >
+ <number>0</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Developer</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Student</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Fisherman</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Profession:</string>
+ </property>
+ <property name="buddy" >
+ <cstring>professionList</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" colspan="3" >
+ <widget class="QComboBox" name="countryCombo" >
+ <property name="toolTip" >
+ <string>Specify country of origin</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify country of origin</string>
+ </property>
+ <property name="currentIndex" >
+ <number>6</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Egypt</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>France</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Germany</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>India</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Italy</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Korea</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Norway</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="countryLabel" >
+ <property name="text" >
+ <string>Pro&amp;fession</string>
+ </property>
+ <property name="buddy" >
+ <cstring>professionList</cstring>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>392</width>
+ <height>25</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menu_File" >
+ <property name="title" >
+ <string>&amp;File</string>
+ </property>
+ <addaction name="editStyleAction" />
+ <addaction name="separator" />
+ <addaction name="exitAction" />
+ </widget>
+ <widget class="QMenu" name="menu_Help" >
+ <property name="title" >
+ <string>&amp;Help</string>
+ </property>
+ <addaction name="aboutAction" />
+ <addaction name="separator" />
+ <addaction name="aboutQtAction" />
+ </widget>
+ <addaction name="menu_File" />
+ <addaction name="menu_Help" />
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ <action name="exitAction" >
+ <property name="text" >
+ <string>&amp;Exit</string>
+ </property>
+ </action>
+ <action name="aboutQtAction" >
+ <property name="text" >
+ <string>About Qt</string>
+ </property>
+ </action>
+ <action name="editStyleAction" >
+ <property name="text" >
+ <string>Edit &amp;Style</string>
+ </property>
+ </action>
+ <action name="aboutAction" >
+ <property name="text" >
+ <string>About</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/main.cpp b/tests/manual/examples/widgets/widgets/stylesheet/main.cpp
new file mode 100644
index 0000000000..7d7cf3e573
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/main.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QApplication>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ MainWindow window;
+ window.show();
+ return app.exec();
+}
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/mainwindow.cpp b/tests/manual/examples/widgets/widgets/stylesheet/mainwindow.cpp
new file mode 100644
index 0000000000..a43613c757
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/mainwindow.cpp
@@ -0,0 +1,41 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "mainwindow.h"
+#include "stylesheeteditor.h"
+
+#include <QMessageBox>
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+{
+ ui.setupUi(this);
+
+ ui.nameLabel->setProperty("class", "mandatory QLabel");
+ ui.nameCombo->lineEdit()->setPlaceholderText(tr("Last, First"));
+
+ styleSheetEditor = new StyleSheetEditor(this);
+
+ statusBar()->addWidget(new QLabel(tr("Ready")));
+
+ connect(ui.exitAction, &QAction::triggered, qApp, &QApplication::quit);
+ connect(ui.aboutQtAction, &QAction::triggered, qApp, &QApplication::aboutQt);
+}
+
+void MainWindow::on_editStyleAction_triggered()
+{
+ styleSheetEditor->show();
+ styleSheetEditor->activateWindow();
+}
+
+void MainWindow::on_aboutAction_triggered()
+{
+ const QString url = QStringLiteral("http://doc.qt.io/qt-%1/stylesheet.html")
+ .arg(QT_VERSION_MAJOR);
+ QMessageBox::about(this, tr("About Style sheet"),
+ tr("The <b>Style Sheet</b> example shows how widgets can be styled "
+ "using <a href=\"%1\">Qt "
+ "Style Sheets</a>. Click <b>File|Edit Style Sheet</b> to pop up the "
+ "style editor, and either choose an existing style sheet or design "
+ "your own.").arg(url));
+}
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/mainwindow.h b/tests/manual/examples/widgets/widgets/stylesheet/mainwindow.h
new file mode 100644
index 0000000000..877636bddf
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/mainwindow.h
@@ -0,0 +1,29 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QMainWindow>
+
+#include "ui_mainwindow.h"
+
+class StyleSheetEditor;
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ MainWindow(QWidget *parent = nullptr);
+
+private slots:
+ void on_editStyleAction_triggered();
+ void on_aboutAction_triggered();
+
+private:
+ StyleSheetEditor *styleSheetEditor;
+ Ui::MainWindow ui;
+};
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/mainwindow.ui b/tests/manual/examples/widgets/widgets/stylesheet/mainwindow.ui
new file mode 100644
index 0000000000..cc29257afb
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/mainwindow.ui
@@ -0,0 +1,356 @@
+<ui version="4.0" >
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>413</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Style Sheet</string>
+ </property>
+ <widget class="QWidget" name="centralwidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QFrame" name="mainFrame" >
+ <property name="frameShape" >
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="6" column="0" colspan="5" >
+ <widget class="QCheckBox" name="agreeCheckBox" >
+ <property name="toolTip" >
+ <string>Please read the LICENSE file before checking</string>
+ </property>
+ <property name="text" >
+ <string>I accept the terms and &amp;conditions</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Profession:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
+ </property>
+ <property name="buddy" >
+ <cstring>professionList</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="nameLabel" >
+ <property name="text" >
+ <string>&amp;Name:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy" >
+ <cstring>nameCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QRadioButton" name="maleRadioButton" >
+ <property name="toolTip" >
+ <string>Check this if you are male</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Male</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="passwordLabel" >
+ <property name="text" >
+ <string>&amp;Password:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy" >
+ <cstring>passwordEdit</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1" colspan="4" >
+ <widget class="QComboBox" name="countryCombo" >
+ <property name="toolTip" >
+ <string>Specify country of origin</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify country of origin</string>
+ </property>
+ <property name="currentIndex" >
+ <number>6</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Egypt</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>France</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Germany</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>India</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Italy</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Norway</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Pakistan</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="ageLabel" >
+ <property name="text" >
+ <string>&amp;Age:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy" >
+ <cstring>ageSpinBox</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" >
+ <widget class="QLabel" name="countryLabel" >
+ <property name="text" >
+ <string>Country:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="buddy" >
+ <cstring>countryCombo</cstring>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="genderLabel" >
+ <property name="text" >
+ <string>Gender:</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="4" >
+ <widget class="QLineEdit" name="passwordEdit" >
+ <property name="toolTip" >
+ <string>Specify your password</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify your password</string>
+ </property>
+ <property name="text" >
+ <string>Password</string>
+ </property>
+ <property name="echoMode" >
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" colspan="2" >
+ <widget class="QRadioButton" name="femaleRadioButton" >
+ <property name="toolTip">
+ <string>Check this if you are female</string>
+ </property>
+ <property name="text" >
+ <string>&amp;Female</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" colspan="2" >
+ <widget class="QSpinBox" name="ageSpinBox" >
+ <property name="toolTip" >
+ <string>Specify your age</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify your age</string>
+ </property>
+ <property name="minimum" >
+ <number>12</number>
+ </property>
+ <property name="value" >
+ <number>22</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" colspan="4" >
+ <widget class="QComboBox" name="nameCombo" >
+ <property name="toolTip" >
+ <string>Specify your name</string>
+ </property>
+ <property name="editable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="3" colspan="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>61</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="7" column="3" colspan="2" >
+ <widget class="QDialogButtonBox" name="buttonBox" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons" >
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" colspan="4" >
+ <widget class="QListWidget" name="professionList" >
+ <property name="toolTip" >
+ <string>Select your profession</string>
+ </property>
+ <property name="statusTip" >
+ <string>Specify your name here</string>
+ </property>
+ <property name="whatsThis" >
+ <string>Specify your name here</string>
+ </property>
+ <property name="currentRow" >
+ <number>0</number>
+ </property>
+ <item>
+ <property name="text" >
+ <string>Developer</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Student</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Fisherman</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menubar" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>29</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menu_File" >
+ <property name="title" >
+ <string>&amp;File</string>
+ </property>
+ <addaction name="editStyleAction" />
+ <addaction name="separator" />
+ <addaction name="exitAction" />
+ </widget>
+ <widget class="QMenu" name="menu_Help" >
+ <property name="title" >
+ <string>&amp;Help</string>
+ </property>
+ <addaction name="aboutAction" />
+ <addaction name="aboutQtAction" />
+ </widget>
+ <addaction name="menu_File" />
+ <addaction name="menu_Help" />
+ </widget>
+ <widget class="QStatusBar" name="statusbar" />
+ <action name="exitAction" >
+ <property name="text" >
+ <string>&amp;Exit</string>
+ </property>
+ </action>
+ <action name="aboutQtAction" >
+ <property name="text" >
+ <string>About Qt</string>
+ </property>
+ </action>
+ <action name="editStyleAction" >
+ <property name="text" >
+ <string>Edit &amp;Style...</string>
+ </property>
+ </action>
+ <action name="aboutAction" >
+ <property name="text" >
+ <string>About</string>
+ </property>
+ </action>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/qss/coffee.qss b/tests/manual/examples/widgets/widgets/stylesheet/qss/coffee.qss
new file mode 100644
index 0000000000..8f72a15ee5
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/qss/coffee.qss
@@ -0,0 +1,117 @@
+.QWidget {
+ background-color: beige;
+}
+
+/* Nice Windows-XP-style password character. */
+QLineEdit[echoMode="2"] {
+ lineedit-password-character: 9679;
+}
+
+/* We provide a min-width and min-height for push buttons
+ so that they look elegant regardless of the width of the text. */
+QPushButton {
+ background-color: palegoldenrod;
+ border-width: 2px;
+ border-color: darkkhaki;
+ border-style: solid;
+ border-radius: 5;
+ padding: 3px;
+ min-width: 9ex;
+ min-height: 2.5ex;
+}
+
+QPushButton:hover {
+ background-color: khaki;
+}
+
+/* Increase the padding, so the text is shifted when the button is
+ pressed. */
+QPushButton:pressed {
+ padding-left: 5px;
+ padding-top: 5px;
+ background-color: #d0d67c;
+}
+
+QLabel, QAbstractButton {
+ font: bold;
+}
+
+/* Mark mandatory fields with a brownish color. */
+.mandatory {
+ color: brown;
+}
+
+/* Bold text on status bar looks awful. */
+QStatusBar QLabel {
+ font: normal;
+}
+
+QStatusBar::item {
+ border-width: 1;
+ border-color: darkkhaki;
+ border-style: solid;
+ border-radius: 2;
+}
+
+QComboBox, QLineEdit, QSpinBox, QTextEdit, QListView {
+ background-color: cornsilk;
+ selection-color: #0a214c;
+ selection-background-color: #C19A6B;
+}
+
+/* Make placeholder text a matching semi-transparent color */
+QComboBox, QLineEdit {
+ placeholder-text-color: #80C19A6B;
+}
+
+QListView {
+ show-decoration-selected: 1;
+}
+
+QListView::item:hover {
+ background-color: wheat;
+}
+
+/* We reserve 1 pixel space in padding. When we get the focus,
+ we kill the padding and enlarge the border. This makes the items
+ glow. */
+QLineEdit, QFrame {
+ border-width: 2px;
+ padding: 1px;
+ border-style: solid;
+ border-color: darkkhaki;
+ border-radius: 5px;
+}
+
+/* As mentioned above, eliminate the padding and increase the border. */
+QLineEdit:focus, QFrame:focus {
+ border-width: 3px;
+ padding: 0px;
+}
+
+/* A QLabel is a QFrame ... */
+QLabel {
+ border: none;
+ padding: 0;
+ background: none;
+}
+
+/* A QToolTip is a QLabel ... */
+QToolTip {
+ border: 2px solid darkkhaki;
+ padding: 5px;
+ border-radius: 3px;
+ opacity: 200;
+}
+
+/* Nice to have the background color change when hovered. */
+QRadioButton:hover, QCheckBox:hover {
+ background-color: wheat;
+}
+
+/* Force the dialog's buttons to follow the Windows guidelines. */
+QDialogButtonBox {
+ button-layout: 0;
+}
+
+
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/qss/default.qss b/tests/manual/examples/widgets/widgets/stylesheet/qss/default.qss
new file mode 100644
index 0000000000..84eb5e0bc2
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/qss/default.qss
@@ -0,0 +1 @@
+/* empty stylesheet */
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/qss/pagefold.qss b/tests/manual/examples/widgets/widgets/stylesheet/qss/pagefold.qss
new file mode 100644
index 0000000000..3701fc713c
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/qss/pagefold.qss
@@ -0,0 +1,299 @@
+/* Customize any plain widget that is a child of a QMainWindow. */
+QMainWindow > .QWidget {
+ background-color: gainsboro;
+ background-image: url(:/images/pagefold.png);
+ background-position: top right;
+ background-repeat: no-repeat
+}
+
+/* Provide a padding for the layout inside the frame. The frame
+ exists only to provide a padding for the top-right image, so we
+ explicitly disable the border. */
+#mainFrame {
+ padding-right: 30px;
+ border-style: none;
+ border-image: none; /* since we set a border-image below */
+}
+
+/* mainFrame won't have this border-image since we have
+ explicitly set it to 'none' using a more specific selector. */
+QFrame, QLineEdit, QComboBox[editable="true"], QSpinBox {
+ border-image: url(:/images/frame.png) 4;
+ border-width: 3;
+}
+
+QLabel {
+ border: none;
+ border-image: none;
+ padding: 0;
+ background: none;
+}
+
+/* Make text in message boxes selectable. */
+QMessageBox {
+ /* LinksAccessibleByMouse | TextSelectableByMouse */
+ messagebox-text-interaction-flags: 5;
+}
+
+/* Set the selection colors for all widgets. */
+QWidget {
+ selection-color: black;
+ selection-background-color: Silver;
+ color: black;
+}
+
+/* Make the entire row selected in item views. */
+QAbstractItemView {
+ show-decoration-selected: 1;
+}
+
+/* Nice WindowsXP-style password character for password line edits. */
+QLineEdit[echoMode="2"] {
+ lineedit-password-character: 9679;
+}
+
+/* Customize tooltips. */
+QToolTip {
+ background-color: rgb(200,200,255);
+ border-color: darkslategray;
+ border-width: 1px;
+ border-style: solid;
+ padding: 3px;
+ font: bold;
+ border-radius: 3px;
+ opacity: 200;
+}
+
+/* Customize radio buttons. */
+
+QRadioButton {
+ spacing: 5px;
+}
+
+QRadioButton::indicator {
+ width: 13px;
+ height: 13px;
+}
+
+QRadioButton::indicator::unchecked {
+ image: url(:/images/radiobutton_unchecked.png);
+}
+
+QRadioButton::indicator:unchecked:hover {
+ image: url(:/images/radiobutton_unchecked_hover.png);
+}
+
+QRadioButton::indicator:unchecked:pressed {
+ image: url(:/images/radiobutton_unchecked_pressed.png);
+}
+
+QRadioButton::indicator::checked {
+ image: url(:/images/radiobutton_checked.png);
+}
+
+QRadioButton::indicator:checked:hover {
+ image: url(:/images/radiobutton_checked_hover.png);
+}
+
+QRadioButton::indicator:checked:pressed {
+ image: url(:/images/radiobutton_checked_pressed.png);
+}
+
+/* Customize arrows. */
+
+*::down-arrow, *::menu-indicator {
+ image: url(:/images/down_arrow.png);
+ width: 7px;
+ height: 7px;
+}
+
+*::down-arrow:disabled, *::down-arrow:off {
+ image: url(:/images/down_arrow_disabled.png);
+}
+
+*::up-arrow {
+ image: url(:/images/up_arrow.png);
+ width: 7px;
+ height: 7px;
+}
+
+*::up-arrow:disabled, *::up-arrow:off {
+ image: url(:/images/up_arrow_disabled.png);
+}
+
+/* Customize push buttons and comboboxes. Our read-only combobox
+ is very similar to a push button, so they share the same border image. */
+
+QPushButton {
+ min-width: 4em;
+}
+
+QPushButton, QComboBox[editable="false"],
+QComboBox[editable="true"]::drop-down {
+ border-image: url(:/images/pushbutton.png) 5;
+ border-width: 5;
+}
+
+QPushButton:hover, QComboBox[editable="false"]:hover,
+QComboBox[editable="true"]::drop-down:hover, QMenuBar::item:hover {
+ border-image: url(:/images/pushbutton_hover.png) 5;
+ border-width: 5;
+}
+
+QPushButton:pressed, QComboBox[editable="false"]:on,
+QComboBox[editable="true"]::drop-down:on, QMenuBar::item:on {
+ border-image: url(:/images/pushbutton_pressed.png) 5;
+ border-width: 5;
+}
+
+/* Customize read-only comboboxes. */
+
+QComboBox[editable="false"] {
+ padding-left: 3px;
+ padding-right: 20px; /* space for the arrow */
+}
+
+QComboBox[editable="false"]::drop-down {
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+ width: 15px;
+ border-left-style: solid;
+ border-left-color: darkgray;
+ border-left-width: 1px;
+}
+
+QComboBox[editable="false"]::down-arrow {
+ subcontrol-origin: content;
+ subcontrol-position: center;
+ position: relative;
+ left: 1px; /* 1 pixel dropdown border */
+}
+
+/* The combobox arrow is on when the popup is open. */
+QComboBox[editable="false"]::down-arrow:on {
+ position: relative;
+ top: 1px;
+ left: 2px;
+}
+
+/* Customize editable comboboxes. */
+
+QComboBox[editable="true"] {
+ padding-right: 16px;
+}
+
+QComboBox[editable="true"]::drop-down {
+ subcontrol-origin: border;
+ subcontrol-position: top right;
+ width: 13px;
+ position: absolute;
+ top: 2px;
+ bottom: 2px;
+ right: 2px;
+}
+
+QComboBox[editable="true"]::drop-down,
+QComboBox[editable="true"]::drop-down:hover,
+QComboBox[editable="true"]::drop-down:on {
+ border-width: 0px;
+ border-left-width: 3px; /* we need only left and center part */
+}
+
+/* Shift the arrow when it's open. */
+QComboBox[editable="true"]::down-arrow:on {
+ position: relative;
+ top: 1px;
+ left: 1px;
+}
+
+/* Customize check boxes. */
+QCheckBox {
+ spacing: 5px;
+}
+
+QCheckBox::indicator {
+ width: 13px;
+ height: 13px;
+}
+
+QCheckBox::indicator:unchecked {
+ image: url(:/images/checkbox_unchecked.png);
+}
+
+QCheckBox::indicator:unchecked:hover {
+ image: url(:/images/checkbox_unchecked_hover.png);
+}
+
+QCheckBox::indicator:unchecked:pressed {
+ image: url(:/images/checkbox_unchecked_pressed.png);
+}
+
+QCheckBox::indicator:checked {
+ image: url(:/images/checkbox_checked.png);
+}
+
+QCheckBox::indicator:checked:hover {
+ image: url(:/images/checkbox_checked_hover.png);
+}
+
+QCheckBox::indicator:checked:pressed {
+ image: url(:/images/checkbox_checked_pressed.png);
+}
+
+/* Customize the size grip. */
+QSizeGrip {
+ image: url(:/images/sizegrip.png);
+ width: 16px;
+ height: 16px;
+}
+
+/* Customize the menu bar. */
+QMenuBar {
+ border-image: none;
+ border-style: none;
+ border-width: 1px;
+ border-bottom-style: solid;
+ border-bottom-color: darkslategray;
+ padding: 2px;
+}
+
+/* Customize spin boxes. */
+
+QSpinBox {
+ padding-right: 15px;
+}
+
+QSpinBox::up-button {
+ subcontrol-origin: border;
+ subcontrol-position: top right;
+
+ width: 16px; /* 16 + 2*1px border-width = 15px padding + 3px parent border */
+ border-image: url(:/images/spinup.png) 1;
+ border-width: 1px;
+}
+
+QSpinBox::up-button:hover {
+ border-image: url(:/images/spinup_hover.png) 1;
+}
+
+QSpinBox::up-button:pressed {
+ border-image: url(:/images/spinup_pressed.png) 1;
+}
+
+QSpinBox::down-button {
+ subcontrol-origin: border;
+ subcontrol-position: bottom right;
+
+ width: 16px;
+ border-image: url(:/images/spindown.png) 1;
+ border-width: 1px;
+ border-top-width: 0;
+}
+
+QSpinBox::down-button:hover {
+ border-image: url(:/images/spindown_hover.png) 1;
+}
+
+QSpinBox::down-button:pressed {
+ border-image: url(:/images/spindown_pressed.png) 1;
+}
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/stylesheet.pro b/tests/manual/examples/widgets/widgets/stylesheet/stylesheet.pro
new file mode 100644
index 0000000000..0fe3187f63
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/stylesheet.pro
@@ -0,0 +1,15 @@
+QT += widgets
+requires(qtConfig(combobox))
+
+HEADERS = mainwindow.h \
+ stylesheeteditor.h
+FORMS = mainwindow.ui \
+ stylesheeteditor.ui
+RESOURCES = stylesheet.qrc
+SOURCES = main.cpp \
+ mainwindow.cpp \
+ stylesheeteditor.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/stylesheet
+INSTALLS += target
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/stylesheet.qrc b/tests/manual/examples/widgets/widgets/stylesheet/stylesheet.qrc
new file mode 100644
index 0000000000..e1e61a920a
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/stylesheet.qrc
@@ -0,0 +1,39 @@
+<RCC>
+<qresource prefix="/">
+ <file>layouts/default.ui</file>
+ <file>layouts/pagefold.ui</file>
+ <file>qss/coffee.qss</file>
+ <file>qss/default.qss</file>
+ <file>qss/pagefold.qss</file>
+ <file>images/pagefold.png</file>
+ <file>images/frame.png</file>
+ <file>images/radiobutton_unchecked.png</file>
+ <file>images/radiobutton_unchecked_pressed.png</file>
+ <file>images/radiobutton_unchecked_hover.png</file>
+ <file>images/radiobutton_checked.png</file>
+ <file>images/radiobutton_checked_pressed.png</file>
+ <file>images/radiobutton_checked_hover.png</file>
+ <file>images/pushbutton.png</file>
+ <file>images/pushbutton_hover.png</file>
+ <file>images/pushbutton_pressed.png</file>
+ <file>images/checkbox_unchecked.png</file>
+ <file>images/checkbox_unchecked_pressed.png</file>
+ <file>images/checkbox_unchecked_hover.png</file>
+ <file>images/checkbox_checked.png</file>
+ <file>images/checkbox_checked_pressed.png</file>
+ <file>images/checkbox_checked_hover.png</file>
+ <file>images/down_arrow.png</file>
+ <file>images/down_arrow_disabled.png</file>
+ <file>images/up_arrow.png</file>
+ <file>images/up_arrow_disabled.png</file>
+ <file>images/sizegrip.png</file>
+ <file>images/spinup.png</file>
+ <file>images/spinup_off.png</file>
+ <file>images/spinup_hover.png</file>
+ <file>images/spinup_pressed.png</file>
+ <file>images/spindown.png</file>
+ <file>images/spindown_off.png</file>
+ <file>images/spindown_hover.png</file>
+ <file>images/spindown_pressed.png</file>
+</qresource>
+</RCC>
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.cpp b/tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.cpp
new file mode 100644
index 0000000000..84fda79a16
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.cpp
@@ -0,0 +1,64 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "stylesheeteditor.h"
+
+#include <QFile>
+#include <QRegularExpression>
+#include <QStyleFactory>
+
+StyleSheetEditor::StyleSheetEditor(QWidget *parent)
+ : QDialog(parent)
+{
+ ui.setupUi(this);
+
+ connect(ui.styleCombo, &QComboBox::textActivated, this, &StyleSheetEditor::setStyleName);
+ connect(ui.styleSheetCombo, &QComboBox::textActivated, this, &StyleSheetEditor::setStyleSheetName);
+ connect(ui.styleTextEdit, &QTextEdit::textChanged, this, &StyleSheetEditor::setModified);
+ connect(ui.applyButton, &QAbstractButton::clicked, this, &StyleSheetEditor::apply);
+
+ QRegularExpression regExp("^.(.*)\\+?Style$");
+ QString defaultStyle = QApplication::style()->metaObject()->className();
+ QRegularExpressionMatch match = regExp.match(defaultStyle);
+
+ if (match.hasMatch())
+ defaultStyle = match.captured(1);
+
+ ui.styleCombo->addItems(QStyleFactory::keys());
+ ui.styleCombo->setCurrentIndex(ui.styleCombo->findText(defaultStyle, Qt::MatchContains));
+ ui.styleSheetCombo->setCurrentIndex(ui.styleSheetCombo->findText("Coffee"));
+ loadStyleSheet("Coffee");
+}
+
+void StyleSheetEditor::setStyleName(const QString &styleName)
+{
+ qApp->setStyle(styleName);
+ ui.applyButton->setEnabled(false);
+}
+
+void StyleSheetEditor::setStyleSheetName(const QString &sheetName)
+{
+ loadStyleSheet(sheetName);
+}
+
+void StyleSheetEditor::setModified()
+{
+ ui.applyButton->setEnabled(true);
+}
+
+void StyleSheetEditor::apply()
+{
+ qApp->setStyleSheet(ui.styleTextEdit->toPlainText());
+ ui.applyButton->setEnabled(false);
+}
+
+void StyleSheetEditor::loadStyleSheet(const QString &sheetName)
+{
+ QFile file(":/qss/" + sheetName.toLower() + ".qss");
+ file.open(QFile::ReadOnly);
+ QString styleSheet = QString::fromLatin1(file.readAll());
+
+ ui.styleTextEdit->setPlainText(styleSheet);
+ qApp->setStyleSheet(styleSheet);
+ ui.applyButton->setEnabled(false);
+}
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.h b/tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.h
new file mode 100644
index 0000000000..e61534a4f9
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.h
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef STYLESHEETEDITOR_H
+#define STYLESHEETEDITOR_H
+
+#include <QDialog>
+
+#include "ui_stylesheeteditor.h"
+
+class StyleSheetEditor : public QDialog
+{
+ Q_OBJECT
+
+public:
+ StyleSheetEditor(QWidget *parent = nullptr);
+
+private slots:
+ void setStyleName(const QString &styleName);
+ void setStyleSheetName(const QString &styleSheetName);
+ void setModified();
+ void apply();
+
+private:
+ void loadStyleSheet(const QString &sheetName);
+
+ Ui::StyleSheetEditor ui;
+};
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.ui b/tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.ui
new file mode 100644
index 0000000000..34cd7f6d04
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/stylesheet/stylesheeteditor.ui
@@ -0,0 +1,171 @@
+<ui version="4.0" >
+ <class>StyleSheetEditor</class>
+ <widget class="QWidget" name="StyleSheetEditor" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>445</width>
+ <height>289</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Style Editor</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="6" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>32</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>32</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="5" >
+ <widget class="QComboBox" name="styleSheetCombo" >
+ <item>
+ <property name="text" >
+ <string>Default</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Coffee</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Pagefold</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType" >
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>10</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QComboBox" name="styleCombo" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLabel" name="label_7" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Style:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="7" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>321</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyButton" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
+ <property name="text" >
+ <string>&amp;Apply</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0" colspan="7" >
+ <widget class="QTextEdit" name="styleTextEdit" />
+ </item>
+ <item row="0" column="4" >
+ <widget class="QLabel" name="label_8" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Style Sheet:</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tests/manual/examples/widgets/widgets/tetrix/CMakeLists.txt b/tests/manual/examples/widgets/widgets/tetrix/CMakeLists.txt
new file mode 100644
index 0000000000..c591684ee6
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/tetrix/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(tetrix LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/tetrix")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+
+qt_standard_project_setup()
+
+qt_add_executable(tetrix
+ main.cpp
+ tetrixboard.cpp tetrixboard.h
+ tetrixpiece.cpp tetrixpiece.h
+ tetrixwindow.cpp tetrixwindow.h
+)
+
+set_target_properties(tetrix PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(tetrix PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+)
+
+install(TARGETS tetrix
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/tests/manual/examples/widgets/widgets/tetrix/main.cpp b/tests/manual/examples/widgets/widgets/tetrix/main.cpp
new file mode 100644
index 0000000000..24791bde26
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/tetrix/main.cpp
@@ -0,0 +1,14 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "tetrixwindow.h"
+
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+ TetrixWindow window;
+ window.show();
+ return app.exec();
+}
diff --git a/tests/manual/examples/widgets/widgets/tetrix/tetrix.pro b/tests/manual/examples/widgets/widgets/tetrix/tetrix.pro
new file mode 100644
index 0000000000..bb9f855fb0
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/tetrix/tetrix.pro
@@ -0,0 +1,13 @@
+QT += widgets
+
+HEADERS = tetrixboard.h \
+ tetrixpiece.h \
+ tetrixwindow.h
+SOURCES = main.cpp \
+ tetrixboard.cpp \
+ tetrixpiece.cpp \
+ tetrixwindow.cpp
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/tetrix
+INSTALLS += target
diff --git a/tests/manual/examples/widgets/widgets/tetrix/tetrixboard.cpp b/tests/manual/examples/widgets/widgets/tetrix/tetrixboard.cpp
new file mode 100644
index 0000000000..0c5771ad89
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/tetrix/tetrixboard.cpp
@@ -0,0 +1,371 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "tetrixboard.h"
+
+#include <QKeyEvent>
+#include <QLabel>
+#include <QPainter>
+
+//! [0]
+TetrixBoard::TetrixBoard(QWidget *parent)
+ : QFrame(parent), isStarted(false), isPaused(false)
+{
+ setFrameStyle(QFrame::Panel | QFrame::Sunken);
+ setFocusPolicy(Qt::StrongFocus);
+ clearBoard();
+
+ nextPiece.setRandomShape();
+}
+//! [0]
+
+//! [1]
+void TetrixBoard::setNextPieceLabel(QLabel *label)
+{
+ nextPieceLabel = label;
+}
+//! [1]
+
+//! [2]
+QSize TetrixBoard::sizeHint() const
+{
+ return QSize(BoardWidth * 15 + frameWidth() * 2,
+ BoardHeight * 15 + frameWidth() * 2);
+}
+
+QSize TetrixBoard::minimumSizeHint() const
+//! [2] //! [3]
+{
+ return QSize(BoardWidth * 5 + frameWidth() * 2,
+ BoardHeight * 5 + frameWidth() * 2);
+}
+//! [3]
+
+//! [4]
+void TetrixBoard::start()
+{
+ if (isPaused)
+ return;
+
+ isStarted = true;
+ isWaitingAfterLine = false;
+ numLinesRemoved = 0;
+ numPiecesDropped = 0;
+ score = 0;
+ level = 1;
+ clearBoard();
+
+ emit linesRemovedChanged(numLinesRemoved);
+ emit scoreChanged(score);
+ emit levelChanged(level);
+
+ newPiece();
+ timer.start(timeoutTime(), this);
+}
+//! [4]
+
+//! [5]
+void TetrixBoard::pause()
+{
+ if (!isStarted)
+ return;
+
+ isPaused = !isPaused;
+ if (isPaused) {
+ timer.stop();
+ } else {
+ timer.start(timeoutTime(), this);
+ }
+ update();
+//! [5] //! [6]
+}
+//! [6]
+
+//! [7]
+void TetrixBoard::paintEvent(QPaintEvent *event)
+{
+ QFrame::paintEvent(event);
+
+ QPainter painter(this);
+ QRect rect = contentsRect();
+//! [7]
+
+ if (isPaused) {
+ painter.drawText(rect, Qt::AlignCenter, tr("Pause"));
+ return;
+ }
+
+//! [8]
+ int boardTop = rect.bottom() - BoardHeight*squareHeight();
+
+ for (int i = 0; i < BoardHeight; ++i) {
+ for (int j = 0; j < BoardWidth; ++j) {
+ TetrixShape shape = shapeAt(j, BoardHeight - i - 1);
+ if (shape != NoShape)
+ drawSquare(painter, rect.left() + j * squareWidth(),
+ boardTop + i * squareHeight(), shape);
+ }
+//! [8] //! [9]
+ }
+//! [9]
+
+//! [10]
+ if (curPiece.shape() != NoShape) {
+ for (int i = 0; i < 4; ++i) {
+ int x = curX + curPiece.x(i);
+ int y = curY - curPiece.y(i);
+ drawSquare(painter, rect.left() + x * squareWidth(),
+ boardTop + (BoardHeight - y - 1) * squareHeight(),
+ curPiece.shape());
+ }
+//! [10] //! [11]
+ }
+//! [11] //! [12]
+}
+//! [12]
+
+//! [13]
+void TetrixBoard::keyPressEvent(QKeyEvent *event)
+{
+ if (!isStarted || isPaused || curPiece.shape() == NoShape) {
+ QFrame::keyPressEvent(event);
+ return;
+ }
+//! [13]
+
+//! [14]
+ switch (event->key()) {
+ case Qt::Key_Left:
+ tryMove(curPiece, curX - 1, curY);
+ break;
+ case Qt::Key_Right:
+ tryMove(curPiece, curX + 1, curY);
+ break;
+ case Qt::Key_Down:
+ tryMove(curPiece.rotatedRight(), curX, curY);
+ break;
+ case Qt::Key_Up:
+ tryMove(curPiece.rotatedLeft(), curX, curY);
+ break;
+ case Qt::Key_Space:
+ dropDown();
+ break;
+ case Qt::Key_D:
+ oneLineDown();
+ break;
+ default:
+ QFrame::keyPressEvent(event);
+ }
+//! [14]
+}
+
+//! [15]
+void TetrixBoard::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == timer.timerId()) {
+ if (isWaitingAfterLine) {
+ isWaitingAfterLine = false;
+ newPiece();
+ timer.start(timeoutTime(), this);
+ } else {
+ oneLineDown();
+ }
+ } else {
+ QFrame::timerEvent(event);
+//! [15] //! [16]
+ }
+//! [16] //! [17]
+}
+//! [17]
+
+//! [18]
+void TetrixBoard::clearBoard()
+{
+ for (int i = 0; i < BoardHeight * BoardWidth; ++i)
+ board[i] = NoShape;
+}
+//! [18]
+
+//! [19]
+void TetrixBoard::dropDown()
+{
+ int dropHeight = 0;
+ int newY = curY;
+ while (newY > 0) {
+ if (!tryMove(curPiece, curX, newY - 1))
+ break;
+ --newY;
+ ++dropHeight;
+ }
+ pieceDropped(dropHeight);
+//! [19] //! [20]
+}
+//! [20]
+
+//! [21]
+void TetrixBoard::oneLineDown()
+{
+ if (!tryMove(curPiece, curX, curY - 1))
+ pieceDropped(0);
+}
+//! [21]
+
+//! [22]
+void TetrixBoard::pieceDropped(int dropHeight)
+{
+ for (int i = 0; i < 4; ++i) {
+ int x = curX + curPiece.x(i);
+ int y = curY - curPiece.y(i);
+ shapeAt(x, y) = curPiece.shape();
+ }
+
+ ++numPiecesDropped;
+ if (numPiecesDropped % 25 == 0) {
+ ++level;
+ timer.start(timeoutTime(), this);
+ emit levelChanged(level);
+ }
+
+ score += dropHeight + 7;
+ emit scoreChanged(score);
+ removeFullLines();
+
+ if (!isWaitingAfterLine)
+ newPiece();
+//! [22] //! [23]
+}
+//! [23]
+
+//! [24]
+void TetrixBoard::removeFullLines()
+{
+ int numFullLines = 0;
+
+ for (int i = BoardHeight - 1; i >= 0; --i) {
+ bool lineIsFull = true;
+
+ for (int j = 0; j < BoardWidth; ++j) {
+ if (shapeAt(j, i) == NoShape) {
+ lineIsFull = false;
+ break;
+ }
+ }
+
+ if (lineIsFull) {
+//! [24] //! [25]
+ ++numFullLines;
+ for (int k = i; k < BoardHeight - 1; ++k) {
+ for (int j = 0; j < BoardWidth; ++j)
+ shapeAt(j, k) = shapeAt(j, k + 1);
+ }
+//! [25] //! [26]
+ for (int j = 0; j < BoardWidth; ++j)
+ shapeAt(j, BoardHeight - 1) = NoShape;
+ }
+//! [26] //! [27]
+ }
+//! [27]
+
+//! [28]
+ if (numFullLines > 0) {
+ numLinesRemoved += numFullLines;
+ score += 10 * numFullLines;
+ emit linesRemovedChanged(numLinesRemoved);
+ emit scoreChanged(score);
+
+ timer.start(500, this);
+ isWaitingAfterLine = true;
+ curPiece.setShape(NoShape);
+ update();
+ }
+//! [28] //! [29]
+}
+//! [29]
+
+//! [30]
+void TetrixBoard::newPiece()
+{
+ curPiece = nextPiece;
+ nextPiece.setRandomShape();
+ showNextPiece();
+ curX = BoardWidth / 2 + 1;
+ curY = BoardHeight - 1 + curPiece.minY();
+
+ if (!tryMove(curPiece, curX, curY)) {
+ curPiece.setShape(NoShape);
+ timer.stop();
+ isStarted = false;
+ }
+//! [30] //! [31]
+}
+//! [31]
+
+//! [32]
+void TetrixBoard::showNextPiece()
+{
+ if (!nextPieceLabel)
+ return;
+
+ int dx = nextPiece.maxX() - nextPiece.minX() + 1;
+ int dy = nextPiece.maxY() - nextPiece.minY() + 1;
+
+ QPixmap pixmap(dx * squareWidth(), dy * squareHeight());
+ QPainter painter(&pixmap);
+ painter.fillRect(pixmap.rect(), nextPieceLabel->palette().window());
+
+ for (int i = 0; i < 4; ++i) {
+ int x = nextPiece.x(i) - nextPiece.minX();
+ int y = nextPiece.y(i) - nextPiece.minY();
+ drawSquare(painter, x * squareWidth(), y * squareHeight(),
+ nextPiece.shape());
+ }
+ nextPieceLabel->setPixmap(pixmap);
+//! [32] //! [33]
+}
+//! [33]
+
+//! [34]
+bool TetrixBoard::tryMove(const TetrixPiece &newPiece, int newX, int newY)
+{
+ for (int i = 0; i < 4; ++i) {
+ int x = newX + newPiece.x(i);
+ int y = newY - newPiece.y(i);
+ if (x < 0 || x >= BoardWidth || y < 0 || y >= BoardHeight)
+ return false;
+ if (shapeAt(x, y) != NoShape)
+ return false;
+ }
+//! [34]
+
+//! [35]
+ curPiece = newPiece;
+ curX = newX;
+ curY = newY;
+ update();
+ return true;
+}
+//! [35]
+
+//! [36]
+void TetrixBoard::drawSquare(QPainter &painter, int x, int y, TetrixShape shape)
+{
+ static constexpr QRgb colorTable[8] = {
+ 0x000000, 0xCC6666, 0x66CC66, 0x6666CC,
+ 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00
+ };
+
+ QColor color = colorTable[int(shape)];
+ painter.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2,
+ color);
+
+ painter.setPen(color.lighter());
+ painter.drawLine(x, y + squareHeight() - 1, x, y);
+ painter.drawLine(x, y, x + squareWidth() - 1, y);
+
+ painter.setPen(color.darker());
+ painter.drawLine(x + 1, y + squareHeight() - 1,
+ x + squareWidth() - 1, y + squareHeight() - 1);
+ painter.drawLine(x + squareWidth() - 1, y + squareHeight() - 1,
+ x + squareWidth() - 1, y + 1);
+}
+//! [36]
diff --git a/tests/manual/examples/widgets/widgets/tetrix/tetrixboard.h b/tests/manual/examples/widgets/widgets/tetrix/tetrixboard.h
new file mode 100644
index 0000000000..c2fe3fd01e
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/tetrix/tetrixboard.h
@@ -0,0 +1,79 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef TETRIXBOARD_H
+#define TETRIXBOARD_H
+
+#include <QBasicTimer>
+#include <QFrame>
+#include <QPointer>
+
+#include "tetrixpiece.h"
+
+QT_BEGIN_NAMESPACE
+class QLabel;
+QT_END_NAMESPACE
+
+//! [0]
+class TetrixBoard : public QFrame
+{
+ Q_OBJECT
+
+public:
+ TetrixBoard(QWidget *parent = nullptr);
+
+ void setNextPieceLabel(QLabel *label);
+ QSize sizeHint() const override;
+ QSize minimumSizeHint() const override;
+
+public slots:
+ void start();
+ void pause();
+
+signals:
+ void scoreChanged(int score);
+ void levelChanged(int level);
+ void linesRemovedChanged(int numLines);
+
+protected:
+ void paintEvent(QPaintEvent *event) override;
+ void keyPressEvent(QKeyEvent *event) override;
+ void timerEvent(QTimerEvent *event) override;
+//! [0]
+
+//! [1]
+private:
+ enum { BoardWidth = 10, BoardHeight = 22 };
+
+ TetrixShape &shapeAt(int x, int y) { return board[(y * BoardWidth) + x]; }
+ int timeoutTime() { return 1000 / (1 + level); }
+ int squareWidth() { return contentsRect().width() / BoardWidth; }
+ int squareHeight() { return contentsRect().height() / BoardHeight; }
+ void clearBoard();
+ void dropDown();
+ void oneLineDown();
+ void pieceDropped(int dropHeight);
+ void removeFullLines();
+ void newPiece();
+ void showNextPiece();
+ bool tryMove(const TetrixPiece &newPiece, int newX, int newY);
+ void drawSquare(QPainter &painter, int x, int y, TetrixShape shape);
+
+ QBasicTimer timer;
+ QPointer<QLabel> nextPieceLabel;
+ bool isStarted;
+ bool isPaused;
+ bool isWaitingAfterLine;
+ TetrixPiece curPiece;
+ TetrixPiece nextPiece;
+ int curX;
+ int curY;
+ int numLinesRemoved;
+ int numPiecesDropped;
+ int score;
+ int level;
+ TetrixShape board[BoardWidth * BoardHeight];
+};
+//! [1]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/tetrix/tetrixpiece.cpp b/tests/manual/examples/widgets/widgets/tetrix/tetrixpiece.cpp
new file mode 100644
index 0000000000..5dc9e11c49
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/tetrix/tetrixpiece.cpp
@@ -0,0 +1,106 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "tetrixpiece.h"
+
+#include <QtCore>
+
+//! [0]
+void TetrixPiece::setRandomShape()
+{
+ setShape(TetrixShape(QRandomGenerator::global()->bounded(7) + 1));
+}
+//! [0]
+
+//! [1]
+void TetrixPiece::setShape(TetrixShape shape)
+{
+ static constexpr int coordsTable[8][4][2] = {
+ { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
+ { { 0, -1 }, { 0, 0 }, { -1, 0 }, { -1, 1 } },
+ { { 0, -1 }, { 0, 0 }, { 1, 0 }, { 1, 1 } },
+ { { 0, -1 }, { 0, 0 }, { 0, 1 }, { 0, 2 } },
+ { { -1, 0 }, { 0, 0 }, { 1, 0 }, { 0, 1 } },
+ { { 0, 0 }, { 1, 0 }, { 0, 1 }, { 1, 1 } },
+ { { -1, -1 }, { 0, -1 }, { 0, 0 }, { 0, 1 } },
+ { { 1, -1 }, { 0, -1 }, { 0, 0 }, { 0, 1 } }
+ };
+
+ for (int i = 0; i < 4 ; i++) {
+ for (int j = 0; j < 2; ++j)
+ coords[i][j] = coordsTable[shape][i][j];
+ }
+ pieceShape = shape;
+//! [1] //! [2]
+}
+//! [2]
+
+//! [3]
+int TetrixPiece::minX() const
+{
+ int min = coords[0][0];
+ for (int i = 1; i < 4; ++i)
+ min = qMin(min, coords[i][0]);
+ return min;
+}
+
+int TetrixPiece::maxX() const
+//! [3] //! [4]
+{
+ int max = coords[0][0];
+ for (int i = 1; i < 4; ++i)
+ max = qMax(max, coords[i][0]);
+ return max;
+}
+//! [4]
+
+//! [5]
+int TetrixPiece::minY() const
+{
+ int min = coords[0][1];
+ for (int i = 1; i < 4; ++i)
+ min = qMin(min, coords[i][1]);
+ return min;
+}
+
+int TetrixPiece::maxY() const
+//! [5] //! [6]
+{
+ int max = coords[0][1];
+ for (int i = 1; i < 4; ++i)
+ max = qMax(max, coords[i][1]);
+ return max;
+}
+//! [6]
+
+//! [7]
+TetrixPiece TetrixPiece::rotatedLeft() const
+{
+ if (pieceShape == SquareShape)
+ return *this;
+
+ TetrixPiece result;
+ result.pieceShape = pieceShape;
+ for (int i = 0; i < 4; ++i) {
+ result.setX(i, y(i));
+ result.setY(i, -x(i));
+ }
+//! [7]
+ return result;
+}
+
+//! [9]
+TetrixPiece TetrixPiece::rotatedRight() const
+{
+ if (pieceShape == SquareShape)
+ return *this;
+
+ TetrixPiece result;
+ result.pieceShape = pieceShape;
+ for (int i = 0; i < 4; ++i) {
+ result.setX(i, -y(i));
+ result.setY(i, x(i));
+ }
+//! [9]
+ return result;
+}
diff --git a/tests/manual/examples/widgets/widgets/tetrix/tetrixpiece.h b/tests/manual/examples/widgets/widgets/tetrix/tetrixpiece.h
new file mode 100644
index 0000000000..86a513a76e
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/tetrix/tetrixpiece.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef TETRIXPIECE_H
+#define TETRIXPIECE_H
+
+enum TetrixShape { NoShape, ZShape, SShape, LineShape, TShape, SquareShape,
+ LShape, MirroredLShape };
+
+//! [0]
+class TetrixPiece
+{
+public:
+ TetrixPiece() { setShape(NoShape); }
+
+ void setRandomShape();
+ void setShape(TetrixShape shape);
+
+ TetrixShape shape() const { return pieceShape; }
+ int x(int index) const { return coords[index][0]; }
+ int y(int index) const { return coords[index][1]; }
+ int minX() const;
+ int maxX() const;
+ int minY() const;
+ int maxY() const;
+ TetrixPiece rotatedLeft() const;
+ TetrixPiece rotatedRight() const;
+
+private:
+ void setX(int index, int x) { coords[index][0] = x; }
+ void setY(int index, int y) { coords[index][1] = y; }
+
+ TetrixShape pieceShape;
+ int coords[4][2];
+};
+//! [0]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/tetrix/tetrixwindow.cpp b/tests/manual/examples/widgets/widgets/tetrix/tetrixwindow.cpp
new file mode 100644
index 0000000000..ae10a778e7
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/tetrix/tetrixwindow.cpp
@@ -0,0 +1,82 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "tetrixboard.h"
+#include "tetrixwindow.h"
+
+#include <QCoreApplication>
+#include <QGridLayout>
+#include <QLabel>
+#include <QLCDNumber>
+#include <QPushButton>
+
+//! [0]
+TetrixWindow::TetrixWindow(QWidget *parent)
+ : QWidget(parent), board(new TetrixBoard)
+{
+//! [0]
+ nextPieceLabel = new QLabel;
+ nextPieceLabel->setFrameStyle(QFrame::Box | QFrame::Raised);
+ nextPieceLabel->setAlignment(Qt::AlignCenter);
+ board->setNextPieceLabel(nextPieceLabel);
+//! [1]
+ scoreLcd = new QLCDNumber(5);
+ scoreLcd->setSegmentStyle(QLCDNumber::Filled);
+//! [1]
+ levelLcd = new QLCDNumber(2);
+ levelLcd->setSegmentStyle(QLCDNumber::Filled);
+ linesLcd = new QLCDNumber(5);
+ linesLcd->setSegmentStyle(QLCDNumber::Filled);
+
+//! [2]
+ startButton = new QPushButton(tr("&Start"));
+ startButton->setFocusPolicy(Qt::NoFocus);
+ quitButton = new QPushButton(tr("&Quit"));
+ quitButton->setFocusPolicy(Qt::NoFocus);
+ pauseButton = new QPushButton(tr("&Pause"));
+//! [2] //! [3]
+ pauseButton->setFocusPolicy(Qt::NoFocus);
+//! [3] //! [4]
+
+ connect(startButton, &QPushButton::clicked, board, &TetrixBoard::start);
+//! [4] //! [5]
+ connect(quitButton , &QPushButton::clicked, qApp, &QCoreApplication::quit);
+ connect(pauseButton, &QPushButton::clicked, board, &TetrixBoard::pause);
+ connect(board, &TetrixBoard::scoreChanged,
+ scoreLcd, qOverload<int>(&QLCDNumber::display));
+ connect(board, &TetrixBoard::levelChanged,
+ levelLcd, qOverload<int>(&QLCDNumber::display));
+ connect(board, &TetrixBoard::linesRemovedChanged,
+ linesLcd, qOverload<int>(&QLCDNumber::display));
+//! [5]
+
+//! [6]
+ QGridLayout *layout = new QGridLayout;
+ layout->addWidget(createLabel(tr("NEXT")), 0, 0);
+ layout->addWidget(nextPieceLabel, 1, 0);
+ layout->addWidget(createLabel(tr("LEVEL")), 2, 0);
+ layout->addWidget(levelLcd, 3, 0);
+ layout->addWidget(startButton, 4, 0);
+ layout->addWidget(board, 0, 1, 6, 1);
+ layout->addWidget(createLabel(tr("SCORE")), 0, 2);
+ layout->addWidget(scoreLcd, 1, 2);
+ layout->addWidget(createLabel(tr("LINES REMOVED")), 2, 2);
+ layout->addWidget(linesLcd, 3, 2);
+ layout->addWidget(quitButton, 4, 2);
+ layout->addWidget(pauseButton, 5, 2);
+ setLayout(layout);
+
+ setWindowTitle(tr("Tetrix"));
+ resize(550, 370);
+}
+//! [6]
+
+//! [7]
+QLabel *TetrixWindow::createLabel(const QString &text)
+{
+ QLabel *label = new QLabel(text);
+ label->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
+ return label;
+}
+//! [7]
+
diff --git a/tests/manual/examples/widgets/widgets/tetrix/tetrixwindow.h b/tests/manual/examples/widgets/widgets/tetrix/tetrixwindow.h
new file mode 100644
index 0000000000..2ed468717d
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/tetrix/tetrixwindow.h
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef TETRIXWINDOW_H
+#define TETRIXWINDOW_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QLCDNumber;
+class QLabel;
+class QPushButton;
+QT_END_NAMESPACE
+class TetrixBoard;
+
+//! [0]
+class TetrixWindow : public QWidget
+{
+ Q_OBJECT
+
+public:
+ TetrixWindow(QWidget *parent = nullptr);
+
+private:
+ QLabel *createLabel(const QString &text);
+
+ TetrixBoard *board;
+ QLabel *nextPieceLabel;
+ QLCDNumber *scoreLcd;
+ QLCDNumber *levelLcd;
+ QLCDNumber *linesLcd;
+ QPushButton *startButton;
+ QPushButton *quitButton;
+ QPushButton *pauseButton;
+};
+//! [0]
+
+#endif
diff --git a/tests/manual/examples/widgets/widgets/validators/CMakeLists.txt b/tests/manual/examples/widgets/widgets/validators/CMakeLists.txt
new file mode 100644
index 0000000000..653b8eba78
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/CMakeLists.txt
@@ -0,0 +1,55 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(validators LANGUAGES CXX)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/widgets/widgets/validators")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
+
+qt_standard_project_setup()
+
+qt_add_executable(validators
+ ledwidget.cpp ledwidget.h
+ localeselector.cpp localeselector.h
+ main.cpp
+ validators.ui
+ validatorwidget.cpp validatorwidget.h
+)
+
+set_target_properties(validators PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(validators PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Widgets
+)
+
+# Resources:
+set(validators_resource_files
+ "ledoff.png"
+ "ledon.png"
+)
+
+qt_add_resources(validators "validators"
+ PREFIX
+ "/"
+ FILES
+ ${validators_resource_files}
+)
+
+install(TARGETS validators
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/tests/manual/examples/widgets/widgets/validators/ledoff.png b/tests/manual/examples/widgets/widgets/validators/ledoff.png
new file mode 100644
index 0000000000..8b1f2ed123
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/ledoff.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/validators/ledon.png b/tests/manual/examples/widgets/widgets/validators/ledon.png
new file mode 100644
index 0000000000..601c34d5a8
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/ledon.png
Binary files differ
diff --git a/tests/manual/examples/widgets/widgets/validators/ledwidget.cpp b/tests/manual/examples/widgets/widgets/validators/ledwidget.cpp
new file mode 100644
index 0000000000..5b95595a75
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/ledwidget.cpp
@@ -0,0 +1,25 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "ledwidget.h"
+
+LEDWidget::LEDWidget(QWidget *parent)
+ : QLabel(parent), onPixmap(":/ledon.png"), offPixmap(":/ledoff.png")
+{
+ setPixmap(offPixmap);
+ flashTimer.setInterval(200);
+ flashTimer.setSingleShot(true);
+ connect(&flashTimer, &QTimer::timeout, this, &LEDWidget::extinguish);
+};
+
+void LEDWidget::extinguish()
+{
+ setPixmap(offPixmap);
+}
+
+void LEDWidget::flash()
+{
+ setPixmap(onPixmap);
+ flashTimer.start();
+}
+
diff --git a/tests/manual/examples/widgets/widgets/validators/ledwidget.h b/tests/manual/examples/widgets/widgets/validators/ledwidget.h
new file mode 100644
index 0000000000..81215b668f
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/ledwidget.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef LEDWIDGET_H
+#define LEDWIDGET_H
+
+#include <QLabel>
+#include <QPixmap>
+#include <QTimer>
+
+class LEDWidget : public QLabel
+{
+ Q_OBJECT
+public:
+ LEDWidget(QWidget *parent = nullptr);
+public slots:
+ void flash();
+
+private slots:
+ void extinguish();
+
+private:
+ QPixmap onPixmap, offPixmap;
+ QTimer flashTimer;
+};
+
+#endif // LEDWIDGET_H
diff --git a/tests/manual/examples/widgets/widgets/validators/localeselector.cpp b/tests/manual/examples/widgets/widgets/validators/localeselector.cpp
new file mode 100644
index 0000000000..c74faa8c9d
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/localeselector.cpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "localeselector.h"
+
+#include <QLocale>
+
+LocaleSelector::LocaleSelector(QWidget *parent)
+ : QComboBox(parent)
+{
+ int curIndex = -1;
+ int index = 0;
+ for (int _lang = QLocale::C; _lang <= QLocale::LastLanguage; ++_lang) {
+ QLocale::Language lang = static_cast<QLocale::Language>(_lang);
+ const QList<QLocale> locales =
+ QLocale::matchingLocales(lang, QLocale::AnyScript, QLocale::AnyTerritory);
+ for (const QLocale &l : locales) {
+ QString label = QLocale::languageToString(l.language());
+ label += QLatin1Char('/');
+ label += QLocale::territoryToString(l.territory());
+ // distinguish locales by script, if there are more than one script for a language/territory pair
+ if (QLocale::matchingLocales(l.language(), QLocale::AnyScript, l.territory()).size() > 1)
+ label += QLatin1String(" (") + QLocale::scriptToString(l.script()) + QLatin1Char(')');
+
+ addItem(label, QVariant::fromValue(l));
+
+ if (l.language() == locale().language() && l.territory() == locale().territory()
+ && (locale().script() == QLocale::AnyScript || l.script() == locale().script())) {
+ curIndex = index;
+ }
+ ++index;
+ }
+ }
+ if (curIndex != -1)
+ setCurrentIndex(curIndex);
+
+ connect(this, QOverload<int>::of(&LocaleSelector::activated),
+ this, &LocaleSelector::emitLocaleSelected);
+}
+
+void LocaleSelector::emitLocaleSelected(int index)
+{
+ QVariant v = itemData(index);
+ if (!v.isValid())
+ return;
+ const QLocale l = qvariant_cast<QLocale>(v);
+ emit localeSelected(l);
+}
diff --git a/tests/manual/examples/widgets/widgets/validators/localeselector.h b/tests/manual/examples/widgets/widgets/validators/localeselector.h
new file mode 100644
index 0000000000..c684e18d40
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/localeselector.h
@@ -0,0 +1,23 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef LOCALESELECTOR_H
+#define LOCALESELECTOR_H
+
+#include <QComboBox>
+
+class LocaleSelector : public QComboBox
+{
+ Q_OBJECT
+
+public:
+ LocaleSelector(QWidget *parent = nullptr);
+
+signals:
+ void localeSelected(const QLocale &locale);
+
+private slots:
+ void emitLocaleSelected(int index);
+};
+
+#endif //LOCALESELECTOR_H
diff --git a/tests/manual/examples/widgets/widgets/validators/main.cpp b/tests/manual/examples/widgets/widgets/validators/main.cpp
new file mode 100644
index 0000000000..c09d428416
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/main.cpp
@@ -0,0 +1,16 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "validatorwidget.h"
+
+#include <QApplication>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ ValidatorWidget w;
+ w.show();
+
+ return app.exec();
+}
diff --git a/tests/manual/examples/widgets/widgets/validators/validators.pro b/tests/manual/examples/widgets/widgets/validators/validators.pro
new file mode 100644
index 0000000000..029cf95aca
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/validators.pro
@@ -0,0 +1,12 @@
+QT += widgets
+requires(qtConfig(combobox))
+
+FORMS += validators.ui
+RESOURCES += validators.qrc
+
+SOURCES += main.cpp ledwidget.cpp localeselector.cpp validatorwidget.cpp
+HEADERS += ledwidget.h localeselector.h validatorwidget.h
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/validators
+INSTALLS += target
diff --git a/tests/manual/examples/widgets/widgets/validators/validators.qrc b/tests/manual/examples/widgets/widgets/validators/validators.qrc
new file mode 100644
index 0000000000..94874317a8
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/validators.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/" >
+ <file>ledoff.png</file>
+ <file>ledon.png</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/examples/widgets/widgets/validators/validators.ui b/tests/manual/examples/widgets/widgets/validators/validators.ui
new file mode 100644
index 0000000000..cd984e6b97
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/validators.ui
@@ -0,0 +1,468 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ValidatorsForm</class>
+ <widget class="QWidget" name="ValidatorsForm">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>526</width>
+ <height>443</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Validators</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="LocaleSelector" name="localeSelector"/>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>QIntValidator</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Min:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSpinBox" name="minVal">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimum">
+ <number>-1000000</number>
+ </property>
+ <property name="maximum">
+ <number>1000000</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Max:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QSpinBox" name="maxVal">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimum">
+ <number>-1000000</number>
+ </property>
+ <property name="maximum">
+ <number>1000000</number>
+ </property>
+ <property name="value">
+ <number>1000</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="LEDWidget" name="ledWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="validators.qrc">:/ledoff.png</pixmap>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_7">
+ <property name="text">
+ <string>editingFinished()</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="editor"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>QDoubleValidator</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Min:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QDoubleSpinBox" name="doubleMinVal">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimum">
+ <double>-100000.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>100000.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>0.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Format:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <widget class="QComboBox" name="doubleFormat">
+ <item>
+ <property name="text">
+ <string>Standard</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Scientific</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Max:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QDoubleSpinBox" name="doubleMaxVal">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimum">
+ <double>-100000.000000000000000</double>
+ </property>
+ <property name="maximum">
+ <double>100000.000000000000000</double>
+ </property>
+ <property name="value">
+ <double>1000.000000000000000</double>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Decimals:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3">
+ <widget class="QSpinBox" name="doubleDecimals">
+ <property name="value">
+ <number>2</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame_2">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <layout class="QVBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <item>
+ <widget class="LEDWidget" name="doubleLedWidget">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="validators.qrc">:/ledoff.png</pixmap>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_8">
+ <property name="text">
+ <string>editingFinished()</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="doubleEditor"/>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>111</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="pushButton">
+ <property name="text">
+ <string>Quit</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>LEDWidget</class>
+ <extends>QLabel</extends>
+ <header>ledwidget.h</header>
+ </customwidget>
+ <customwidget>
+ <class>LocaleSelector</class>
+ <extends>QComboBox</extends>
+ <header>localeselector.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="validators.qrc"/>
+ </resources>
+ <connections>
+ <connection>
+ <sender>pushButton</sender>
+ <signal>clicked()</signal>
+ <receiver>ValidatorsForm</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>94</x>
+ <y>274</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>131</x>
+ <y>260</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tests/manual/examples/widgets/widgets/validators/validatorwidget.cpp b/tests/manual/examples/widgets/widgets/validators/validatorwidget.cpp
new file mode 100644
index 0000000000..7782342221
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/validatorwidget.cpp
@@ -0,0 +1,75 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "validatorwidget.h"
+
+#include <QIntValidator>
+
+ValidatorWidget::ValidatorWidget(QWidget *parent)
+ : QWidget(parent)
+{
+ setupUi(this);
+
+ connect(localeSelector, &LocaleSelector::localeSelected,
+ this, &ValidatorWidget::setLocale);
+ connect(localeSelector, &LocaleSelector::localeSelected,
+ this, &ValidatorWidget::updateValidator);
+ connect(localeSelector, &LocaleSelector::localeSelected,
+ this, &ValidatorWidget::updateDoubleValidator);
+
+ connect(minVal, &QSpinBox::editingFinished,
+ this, &ValidatorWidget::updateValidator);
+ connect(maxVal, &QSpinBox::editingFinished,
+ this, &ValidatorWidget::updateValidator);
+ connect(editor, &QLineEdit::editingFinished,
+ ledWidget, &LEDWidget::flash);
+
+ connect(doubleMaxVal, &QDoubleSpinBox::editingFinished,
+ this, &ValidatorWidget::updateDoubleValidator);
+ connect(doubleMinVal, &QDoubleSpinBox::editingFinished,
+ this, &ValidatorWidget::updateDoubleValidator);
+ connect(doubleDecimals, &QSpinBox::valueChanged,
+ this, &ValidatorWidget::updateDoubleValidator);
+ connect(doubleFormat, &QComboBox::activated,
+ this, &ValidatorWidget::updateDoubleValidator);
+ connect(doubleEditor, &QLineEdit::editingFinished,
+ doubleLedWidget, &LEDWidget::flash);
+
+ updateValidator();
+ updateDoubleValidator();
+}
+
+void ValidatorWidget::updateValidator()
+{
+ QIntValidator *v = new QIntValidator(minVal->value(), maxVal->value(), this);
+ v->setLocale(locale());
+ delete editor->validator();
+ editor->setValidator(v);
+
+ QString s = editor->text();
+ int i = 0;
+ if (v->validate(s, i) == QValidator::Invalid) {
+ editor->clear();
+ } else {
+ editor->setText(s);
+ }
+}
+
+void ValidatorWidget::updateDoubleValidator()
+{
+ QDoubleValidator *v
+ = new QDoubleValidator(doubleMinVal->value(), doubleMaxVal->value(),
+ doubleDecimals->value(), this);
+ v->setNotation(static_cast<QDoubleValidator::Notation>(doubleFormat->currentIndex()));
+ v->setLocale(locale());
+ delete doubleEditor->validator();
+ doubleEditor->setValidator(v);
+
+ QString s = doubleEditor->text();
+ int i = 0;
+ if (v->validate(s, i) == QValidator::Invalid) {
+ doubleEditor->clear();
+ } else {
+ doubleEditor->setText(s);
+ }
+}
diff --git a/tests/manual/examples/widgets/widgets/validators/validatorwidget.h b/tests/manual/examples/widgets/widgets/validators/validatorwidget.h
new file mode 100644
index 0000000000..d186c5863b
--- /dev/null
+++ b/tests/manual/examples/widgets/widgets/validators/validatorwidget.h
@@ -0,0 +1,22 @@
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef VALIDATORWIDGET_H
+#define VALIDATORWIDGET_H
+
+#include <QWidget>
+
+#include "ui_validators.h"
+
+class ValidatorWidget : public QWidget, public Ui::ValidatorsForm
+{
+ Q_OBJECT
+public:
+ ValidatorWidget(QWidget *parent = nullptr);
+
+private slots:
+ void updateValidator();
+ void updateDoubleValidator();
+};
+
+#endif // VALIDATORWIDGET_H