diff options
Diffstat (limited to 'tests/manual/highdpi/main.cpp')
-rw-r--r-- | tests/manual/highdpi/main.cpp | 1478 |
1 files changed, 0 insertions, 1478 deletions
diff --git a/tests/manual/highdpi/main.cpp b/tests/manual/highdpi/main.cpp deleted file mode 100644 index 18c29bd9af..0000000000 --- a/tests/manual/highdpi/main.cpp +++ /dev/null @@ -1,1478 +0,0 @@ -/**************************************************************************** - ** - ** Copyright (C) 2016 The Qt Company Ltd. - ** Contact: https://www.qt.io/licensing/ - ** - ** This file is part of the test suite of the Qt Toolkit. - ** - ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ - ** Commercial License Usage - ** Licensees holding valid commercial Qt licenses may use this file in - ** accordance with the commercial license agreement provided with the - ** Software or, alternatively, in accordance with the terms contained in - ** a written agreement between you and The Qt Company. For licensing terms - ** and conditions see https://www.qt.io/terms-conditions. For further - ** information use the contact form at https://www.qt.io/contact-us. - ** - ** GNU General Public License Usage - ** Alternatively, this file may be used under the terms of the GNU - ** General Public License version 3 as published by the Free Software - ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT - ** included in the packaging of this file. Please review the following - ** information to ensure the GNU General Public License requirements will - ** be met: https://www.gnu.org/licenses/gpl-3.0.html. - ** - ** $QT_END_LICENSE$ - ** - ****************************************************************************/ - -#include <QMainWindow> -#include <QMenuBar> -#include <QLabel> -#include <QHBoxLayout> -#include <QFormLayout> -#include <QApplication> -#include <QAction> -#include <QStyle> -#include <QToolBar> -#include <QPushButton> -#include <QButtonGroup> -#include <QLineEdit> -#include <QPlainTextEdit> -#include <QTabWidget> -#include <QScrollBar> -#include <QSlider> -#include <QSpinBox> -#include <QTabBar> -#include <QTextBrowser> -#include <QIcon> -#include <QPainter> -#include <QWindow> -#include <QScreen> -#include <QGraphicsView> -#include <QGraphicsTextItem> -#include <QFile> -#include <QFontMetrics> -#include <QMouseEvent> -#include <QTemporaryDir> -#include <QTimer> -#include <QCommandLineParser> -#include <QCommandLineOption> -#include <QDebug> -#include <QElapsedTimer> -#include <private/qhighdpiscaling_p.h> -#include <qpa/qplatformscreen.h> - -#include "dragwidget.h" - -#include <utility> - -static QTextStream &operator<<(QTextStream &str, const QSizeF &s) -{ - str << s.width() << 'x' << s.height(); - return str; -} - -static QTextStream &operator<<(QTextStream &str, const QRect &r) -{ - str << r.width() << 'x' << r.height() << Qt::forcesign << r.x() << r.y() << Qt::noforcesign; - return str; -} - -static QString formatWindowTitle(const QString &title) -{ - QString result; - QTextStream(&result) << title << ' ' << QT_VERSION_STR << " (" - << QGuiApplication::platformName() - << '/' << QApplication::style()->objectName() << ')'; - return result; -} - -class DemoContainerBase -{ -public: - DemoContainerBase() = default; - virtual ~DemoContainerBase() = default; - QString name() { return option().names().constFirst(); } - virtual QCommandLineOption &option() = 0; - virtual void makeVisible(bool visible, QWidget *parent) = 0; - QWidget *widget() const { return m_widget; } - -protected: - QWidget *m_widget = nullptr; -}; - -using DemoContainerList = QList<DemoContainerBase*>; - -template <class T> -class DemoContainer : public DemoContainerBase -{ -public: - DemoContainer(const QString &optionName, const QString &description) - : m_option(optionName, description) - { - } - ~DemoContainer() { delete m_widget; } - - QCommandLineOption &option() override { return m_option; } - - void makeVisible(bool visible, QWidget *parent) override - { - if (visible && !m_widget) { - m_widget = new T; - if (m_widget->windowTitle().isEmpty()) { - QString title = m_option.description(); - if (title.startsWith("Test ", Qt::CaseInsensitive)) - title.remove(0, 5); - title[0] = title.at(0).toUpper(); - m_widget->setWindowTitle(formatWindowTitle(title)); - } - m_widget->installEventFilter(parent); - } - if (m_widget) - m_widget->setVisible(visible); - } - -private: - QCommandLineOption m_option; -}; - -class LabelSlider : public QObject -{ -Q_OBJECT -public: - LabelSlider(QObject *parent, const QString &text, QGridLayout *layout, int row) - : QObject(parent) - { - QLabel *textLabel = new QLabel(text); - m_slider = new QSlider(); - m_slider->setOrientation(Qt::Horizontal); - m_slider->setMinimum(1); - m_slider->setMaximum(40); - m_slider->setValue(10); - m_slider->setTracking(false); - m_slider->setTickInterval(5); - m_slider->setTickPosition(QSlider::TicksBelow); - m_label = new QLabel("1.0"); - - // set up layouts - layout->addWidget(textLabel, row, 0); - layout->addWidget(m_slider, row, 1); - layout->addWidget(m_label, row, 2); - - // handle slider position change - connect(m_slider, &QSlider::sliderMoved, this, &LabelSlider::updateLabel); - connect(m_slider, &QSlider::valueChanged, this, &LabelSlider::valueChanged); - } - void setValue(int scaleFactor) - { - m_slider->setValue(scaleFactor); - updateLabel(scaleFactor); - } - -private slots: - void updateLabel(int scaleFactor) - { - // slider value is scale factor times ten; - qreal scalefactorF = qreal(scaleFactor) / 10.0; - - // update label, add ".0" if needed. - QString number = QString::number(scalefactorF); - if (!number.contains(QLatin1Char('.'))) - number.append(".0"); - m_label->setText(number); - } - -signals: - void valueChanged(int scaleFactor); - -private: - QSlider *m_slider; - QLabel *m_label; -}; - -static qreal getScreenFactorWithoutPixelDensity(const QScreen *screen) -{ - // this is a hack that relies on knowing the internals of QHighDpiScaling - static const char *scaleFactorProperty = "_q_scaleFactor"; - QVariant screenFactor = screen->property(scaleFactorProperty); - return screenFactor.isValid() ? screenFactor.toReal() : 1.0; -} - -static inline qreal getGlobalScaleFactor() -{ - QScreen *noScreen = nullptr; - return QHighDpiScaling::factor(noScreen); -} - -class DemoController : public QWidget -{ - Q_OBJECT -public: - DemoController(DemoContainerList demos, QCommandLineParser *parser); - ~DemoController(); - -protected: - bool eventFilter(QObject *object, QEvent *event) override; - void closeEvent(QCloseEvent *) override { QCoreApplication::quit(); } - -private slots: - void handleButton(int id, bool toggled); - -private: - DemoContainerList m_demos; - QButtonGroup *m_group; -}; - -DemoController::DemoController(DemoContainerList demos, QCommandLineParser *parser) - : m_demos(std::move(demos)) -{ - setWindowTitle(formatWindowTitle("Screen Scale Factors")); - setObjectName("controller"); // make WindowScaleFactorSetter skip this window - - auto mainLayout = new QVBoxLayout(this); - auto scaleLayout = new QGridLayout; - mainLayout->addLayout(scaleLayout); - - int layoutRow = 0; - LabelSlider *globalScaleSlider = new LabelSlider(this, "Global scale factor", scaleLayout, layoutRow++); - globalScaleSlider->setValue(int(getGlobalScaleFactor() * 10)); - connect(globalScaleSlider, &LabelSlider::valueChanged, [](int scaleFactor){ - // slider value is scale factor times ten; - qreal scalefactorF = qreal(scaleFactor) / 10.0; - QHighDpiScaling::setGlobalFactor(scalefactorF); - }); - - // set up one scale control line per screen - const auto screens = QGuiApplication::screens(); - for (QScreen *screen : screens) { - // create scale control line - QSize screenSize = screen->geometry().size(); - QString screenId = screen->name() + QLatin1Char(' ') + QString::number(screenSize.width()) - + QLatin1Char(' ') + QString::number(screenSize.height()); - LabelSlider *slider = new LabelSlider(this, screenId, scaleLayout, layoutRow++); - slider->setValue(getScreenFactorWithoutPixelDensity(screen) * 10); - - // handle slider value change - connect(slider, &LabelSlider::valueChanged, [screen](int scaleFactor){ - // slider value is scale factor times ten; - qreal scalefactorF = qreal(scaleFactor) / 10.0; - - // set scale factor for screen - qreal oldFactor = QHighDpiScaling::factor(screen); - QHighDpiScaling::setScreenFactor(screen, scalefactorF); - qreal newFactor = QHighDpiScaling::factor(screen); - - qDebug() << "factor was / is" << oldFactor << newFactor; - }); - } - - auto demoLayout = new QFormLayout; - mainLayout->addLayout(demoLayout); - m_group = new QButtonGroup(this); - m_group->setExclusive(false); - - for (int i = 0; i < m_demos.size(); ++i) { - DemoContainerBase *demo = m_demos.at(i); - QString name = demo->name(); - name[0] = name.at(0).toUpper(); - auto button = new QPushButton(name); - button->setCheckable(true); - demoLayout->addRow(demo->option().description(), button); - m_group->addButton(button, i); - - if (parser->isSet(demo->option())) { - demo->makeVisible(true, this); - button->setChecked(true); - } - } - connect(m_group, &QButtonGroup::idToggled, - this, &DemoController::handleButton); -} - -DemoController::~DemoController() -{ - qDeleteAll(m_demos); -} - -bool DemoController::eventFilter(QObject *object, QEvent *event) -{ - if (event->type() == QEvent::Close) { - for (int i = 0; i < m_demos.size(); ++i) { - DemoContainerBase *demo = m_demos.at(i); - if (demo->widget() == object) { - m_group->button(i)->setChecked(false); - break; - } - } - } - return false; -} - -void DemoController::handleButton(int id, bool toggled) -{ - m_demos.at(id)->makeVisible(toggled, this); -} - -class PixmapPainter : public QWidget -{ -public: - PixmapPainter(); - - void paintEvent(QPaintEvent *event) override; - -private: - QPixmap pixmap1X; - QPixmap pixmap2X; - QPixmap pixmapLarge; - QImage image1X; - QImage image2X; - QImage imageLarge; - QIcon qtIcon; -}; - -PixmapPainter::PixmapPainter() -{ - pixmap1X = QPixmap(":/qticon32.png"); - pixmap2X = QPixmap(":/qticon32@2x.png"); - pixmapLarge = QPixmap(":/qticon64.png"); - - image1X = QImage(":/qticon32.png"); - image2X = QImage(":/qticon32@2x.png"); - imageLarge = QImage(":/qticon64.png"); - - qtIcon.addFile(":/qticon32.png"); - qtIcon.addFile(":/qticon32@2x.png"); -} - -void PixmapPainter::paintEvent(QPaintEvent *) -{ - QPainter p(this); - p.fillRect(QRect(QPoint(0, 0), size()), QBrush(Qt::gray)); - - int pixmapPointSize = 32; - int y = 30; - int dy = 90; - - int x = 10; - int dx = 40; - // draw at point -// qDebug() << "paint pixmap" << pixmap1X.devicePixelRatio(); - p.drawPixmap(x, y, pixmap1X); - x+=dx;p.drawPixmap(x, y, pixmap2X); - x+=dx;p.drawPixmap(x, y, pixmapLarge); - x+=dx*2;p.drawPixmap(x, y, qtIcon.pixmap(QSize(pixmapPointSize, pixmapPointSize))); - x+=dx;p.drawImage(x, y, image1X); - x+=dx;p.drawImage(x, y, image2X); - x+=dx;p.drawImage(x, y, imageLarge); - - // draw at 32x32 rect - y+=dy; - x = 10; - p.drawPixmap(QRect(x, y, pixmapPointSize, pixmapPointSize), pixmap1X); - x+=dx;p.drawPixmap(QRect(x, y, pixmapPointSize, pixmapPointSize), pixmap2X); - x+=dx;p.drawPixmap(QRect(x, y, pixmapPointSize, pixmapPointSize), pixmapLarge); - x+=dx;p.drawPixmap(QRect(x, y, pixmapPointSize, pixmapPointSize), qtIcon.pixmap(QSize(pixmapPointSize, pixmapPointSize))); - x+=dx;p.drawImage(QRect(x, y, pixmapPointSize, pixmapPointSize), image1X); - x+=dx;p.drawImage(QRect(x, y, pixmapPointSize, pixmapPointSize), image2X); - x+=dx;p.drawImage(QRect(x, y, pixmapPointSize, pixmapPointSize), imageLarge); - - - // draw at 64x64 rect - y+=dy - 50; - x = 10; - p.drawPixmap(QRect(x, y, pixmapPointSize * 2, pixmapPointSize * 2), pixmap1X); - x+=dx * 2; p.drawPixmap(QRect(x, y, pixmapPointSize * 2, pixmapPointSize * 2), pixmap2X); - x+=dx * 2; p.drawPixmap(QRect(x, y, pixmapPointSize * 2, pixmapPointSize * 2), pixmapLarge); - x+=dx * 2; p.drawPixmap(QRect(x, y, pixmapPointSize * 2, pixmapPointSize * 2), qtIcon.pixmap(QSize(pixmapPointSize, pixmapPointSize))); - x+=dx * 2; p.drawImage(QRect(x, y, pixmapPointSize * 2, pixmapPointSize * 2), image1X); - x+=dx * 2; p.drawImage(QRect(x, y, pixmapPointSize * 2, pixmapPointSize * 2), image2X); - x+=dx * 2; p.drawImage(QRect(x, y, pixmapPointSize * 2, pixmapPointSize * 2), imageLarge); - } - -class TiledPixmapPainter : public QWidget -{ -public: - TiledPixmapPainter(); - - void paintEvent(QPaintEvent *event) override; - -private: - QPixmap pixmap1X; - QPixmap pixmap2X; - QPixmap pixmapLarge; -}; - -TiledPixmapPainter::TiledPixmapPainter() -{ - pixmap1X = QPixmap(":/qticon32.png"); - pixmap2X = QPixmap(":/qticon32@2x.png"); - pixmapLarge = QPixmap(":/qticon64.png"); -} - -void TiledPixmapPainter::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QPainter p(this); - - int xoff = 10; - int yoff = 10; - int tiles = 4; - int pixmapEdge = 32; - int tileAreaEdge = pixmapEdge * tiles; - - // Expected behavior for both 1x and 2x dislays: - // 1x pixmap : 4 x 4 tiles - // large pixmap: 2 x 2 tiles - // 2x pixmap : 4 x 4 tiles - // - // On a 2x display the 2x pixmap tiles - // will be drawn in high resolution. - p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap1X); - yoff += tiles * pixmapEdge + 10; - p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmapLarge); - yoff += tiles * pixmapEdge + 10; - p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap2X); - - // Again, with an offset. The offset is in - // device-independent pixels. - QPoint offset(40, 40); // larger than the pixmap edge size to exercise that code path - yoff = 10; - xoff = 20 + tiles * pixmapEdge ; - p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap1X, offset); - yoff += tiles * pixmapEdge + 10; - p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmapLarge, offset); - yoff += tiles * pixmapEdge + 10; - p.drawTiledPixmap(QRect(xoff, yoff, tileAreaEdge, tileAreaEdge), pixmap2X, offset); -} - -class Labels : public QWidget -{ -public: - Labels(); - -private: - QPixmap pixmap1X; - QPixmap pixmap2X; - QPixmap pixmapLarge; - QIcon qtIcon; -}; - -Labels::Labels() -{ - pixmap1X = QPixmap(":/qticon32.png"); - pixmap2X = QPixmap(":/qticon32@2x.png"); - pixmapLarge = QPixmap(":/qticon64.png"); - - qtIcon.addFile(":/qticon32.png"); - qtIcon.addFile(":/qticon32@2x.png"); - setWindowIcon(qtIcon); - setWindowTitle(formatWindowTitle("Labels")); - - QLabel *label1x = new QLabel(); - label1x->setPixmap(pixmap1X); - QLabel *label2x = new QLabel(); - label2x->setPixmap(pixmap2X); - QLabel *labelIcon = new QLabel(); - labelIcon->setPixmap(qtIcon.pixmap(QSize(32,32))); - QLabel *labelLarge = new QLabel(); - labelLarge->setPixmap(pixmapLarge); - - QHBoxLayout *layout = new QHBoxLayout(this); - layout->addWidget(label1x); //expected low-res on high-dpi displays - layout->addWidget(label2x); //expected high-res on high-dpi displays - layout->addWidget(labelIcon); //expected high-res on high-dpi displays - layout->addWidget(labelLarge); // expected large size and low-res - setLayout(layout); -} - -class MainWindow : public QMainWindow -{ - Q_OBJECT -public: - MainWindow(); - QMenu *addNewMenu(const QString &title, int itemCount = 5); - -private slots: - void maskActionToggled(bool t); - -private: - QIcon qtIcon; - QIcon qtIcon1x; - QIcon qtIcon2x; - - QToolBar *fileToolBar; - QAction *m_maskAction; - int menuCount = 0; -}; - -MainWindow::MainWindow() -{ - // beware that QIcon auto-loads the @2x versions. - qtIcon1x.addFile(":/qticon16.png"); - qtIcon2x.addFile(":/qticon32.png"); - setWindowIcon(qtIcon); - setWindowTitle(formatWindowTitle("MainWindow")); - - fileToolBar = addToolBar(tr("File")); -// fileToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); - fileToolBar->addAction(new QAction(qtIcon1x, QString("1x"), this)); - fileToolBar->addAction(new QAction(qtIcon2x, QString("2x"), this)); - addNewMenu("&Edit"); - addNewMenu("&Build"); - addNewMenu("&Debug", 4); - QMenu *menu = addNewMenu("&Transmogrify", 7); - menu->addSeparator(); - m_maskAction = menu->addAction("Mask"); - m_maskAction->setCheckable(true); - connect(m_maskAction, &QAction::toggled, this, &MainWindow::maskActionToggled); - fileToolBar->addAction(m_maskAction); - addNewMenu("T&ools"); - addNewMenu("&Help", 2); -} - -QMenu *MainWindow::addNewMenu(const QString &title, int itemCount) -{ - QMenu *menu = menuBar()->addMenu(title); - for (int i = 0; i < itemCount; i++) { - menuCount++; - QString s = "Menu item " + QString::number(menuCount); - if (i == 3) { - QMenu *subMenu = menu->addMenu(s); - for (int j = 1; j < 4; j++) - subMenu->addAction(QString::fromLatin1("SubMenu item %1.%2").arg(menuCount).arg(j)); - } else { - menu->addAction(s); - } - } - return menu; -} - -void MainWindow::maskActionToggled(bool t) -{ - if (t) { - QList<QPoint> upperLeftTriangle; - upperLeftTriangle << QPoint(0, 0) << QPoint(width(), 0) << QPoint(0, height()); - setMask(QRegion(QPolygon(upperLeftTriangle))); - } else { - clearMask(); - } -} - -class StandardIcons : public QWidget -{ -public: - void paintEvent(QPaintEvent *) override - { - int x = 10; - int y = 10; - int dx = 50; - int dy = 50; - int maxX = 500; - - for (uint iconIndex = QStyle::SP_TitleBarMenuButton; iconIndex < QStyle::SP_MediaVolumeMuted; ++iconIndex) { - QIcon icon = qApp->style()->standardIcon(QStyle::StandardPixmap(iconIndex)); - QPainter p(this); - p.drawPixmap(x, y, icon.pixmap(dx - 5, dy - 5)); - if (x + dx > maxX) - y+=dy; - x = ((x + dx) % maxX); - } - } -}; - -class Caching : public QWidget -{ -public: - void paintEvent(QPaintEvent *) override - { - QSize layoutSize(75, 75); - - QPainter widgetPainter(this); - widgetPainter.fillRect(QRect(QPoint(0, 0), this->size()), Qt::gray); - - { - const qreal devicePixelRatio = this->windowHandle()->devicePixelRatio(); - QPixmap cache(layoutSize * devicePixelRatio); - cache.setDevicePixelRatio(devicePixelRatio); - - QPainter cachedPainter(&cache); - cachedPainter.fillRect(QRect(0,0, 75, 75), Qt::blue); - cachedPainter.fillRect(QRect(10,10, 55, 55), Qt::red); - cachedPainter.drawEllipse(QRect(10,10, 55, 55)); - - QPainter widgetPainter(this); - widgetPainter.drawPixmap(QPoint(10, 10), cache); - } - - { - const qreal devicePixelRatio = this->windowHandle()->devicePixelRatio(); - QImage cache = QImage(layoutSize * devicePixelRatio, QImage::Format_ARGB32_Premultiplied); - cache.setDevicePixelRatio(devicePixelRatio); - - QPainter cachedPainter(&cache); - cachedPainter.fillRect(QRect(0,0, 75, 75), Qt::blue); - cachedPainter.fillRect(QRect(10,10, 55, 55), Qt::red); - cachedPainter.drawEllipse(QRect(10,10, 55, 55)); - - QPainter widgetPainter(this); - widgetPainter.drawImage(QPoint(95, 10), cache); - } - - } -}; - -class Style : public QWidget -{ -public: - Style() - { - row1 = new QHBoxLayout(this); - - button = new QPushButton(); - button->setText("Test Button"); - row1->addWidget(button); - - lineEdit = new QLineEdit(); - lineEdit->setText("Test Lineedit"); - row1->addWidget(lineEdit); - - slider = new QSlider(); - row1->addWidget(slider); - - row1->addWidget(new QSpinBox); - row1->addWidget(new QScrollBar); - - auto tab = new QTabBar(); - tab->addTab("Foo"); - tab->addTab("Bar"); - row1->addWidget(tab); - } - -private: - QPushButton *button; - QLineEdit *lineEdit; - QSlider *slider; - QHBoxLayout *row1; -}; - -class Fonts : public QWidget -{ -public: - void paintEvent(QPaintEvent *) override - { - QPainter painter(this); - - // Points - int y = 10; - for (int fontSize = 6; fontSize < 18; fontSize += 2) { - QFont font; - font.setPointSize(fontSize); - QString string = QString(QStringLiteral("This text is in point size %1")).arg(fontSize); - painter.setFont(font); - y += (painter.fontMetrics().lineSpacing()); - painter.drawText(10, y, string); - } - - // Pixels - y += painter.fontMetrics().lineSpacing(); - for (int fontSize = 6; fontSize < 18; fontSize += 2) { - QFont font; - font.setPixelSize(fontSize); - QString string = QString(QStringLiteral("This text is in pixel size %1")).arg(fontSize); - painter.setFont(font); - y += (painter.fontMetrics().lineSpacing()); - painter.drawText(10, y, string); - } - } -}; - - -template <typename T> -void apiTestdevicePixelRatioGetter() -{ - if (0) { - T *t = nullptr; - t->devicePixelRatio(); - } -} - -template <typename T> -void apiTestdevicePixelRatioSetter() -{ - if (0) { - T *t = nullptr; - t->setDevicePixelRatio(2.0); - } -} - -void apiTest() -{ - // compile call to devicePixelRatio getter and setter (verify spelling) - apiTestdevicePixelRatioGetter<QWindow>(); - apiTestdevicePixelRatioGetter<QScreen>(); - apiTestdevicePixelRatioGetter<QGuiApplication>(); - - apiTestdevicePixelRatioGetter<QImage>(); - apiTestdevicePixelRatioSetter<QImage>(); - apiTestdevicePixelRatioGetter<QPixmap>(); - apiTestdevicePixelRatioSetter<QPixmap>(); -} - -// Request and draw an icon at different sizes -class IconDrawing : public QWidget -{ -public: - IconDrawing() - { - const QString tempPath = m_temporaryDir.path(); - const QString path32 = tempPath + "/qticon32.png"; - const QString path32_2 = tempPath + "/qticon32-2.png"; - const QString path32_2x = tempPath + "/qticon32@2x.png"; - - QFile::copy(":/qticon32.png", path32_2); - QFile::copy(":/qticon32.png", path32); - QFile::copy(":/qticon32@2x.png", path32_2x); - - iconHighDPI.reset(new QIcon(path32)); // will auto-load @2x version. - iconNormalDpi.reset(new QIcon(path32_2)); // does not have a 2x version. - } - - void paintEvent(QPaintEvent *) override - { - int x = 10; - int y = 10; - int dx = 50; - int dy = 50; - int maxX = 600; - int minSize = 5; - int maxSize = 64; - int sizeIncrement = 5; - - // normal icon - for (int size = minSize; size < maxSize; size += sizeIncrement) { - QPainter p(this); - p.drawPixmap(x, y, iconNormalDpi->pixmap(size, size)); - if (x + dx > maxX) - y+=dy; - x = ((x + dx) % maxX); - } - x = 10; - y+=dy; - - // high-dpi icon - for (int size = minSize; size < maxSize; size += sizeIncrement) { - QPainter p(this); - p.drawPixmap(x, y, iconHighDPI->pixmap(size, size)); - if (x + dx > maxX) - y+=dy; - x = ((x + dx) % maxX); - } - } - -private: - QTemporaryDir m_temporaryDir; - QScopedPointer<QIcon> iconHighDPI; - QScopedPointer<QIcon> iconNormalDpi; -}; - -// Icons on buttons -class Buttons : public QWidget -{ -public: - Buttons() - { - QIcon icon; - icon.addFile(":/qticon16@2x.png"); - - QPushButton *button = new QPushButton(this); - button->setIcon(icon); - button->setText("16@2x"); - - QTabBar *tab = new QTabBar(this); - tab->addTab(QIcon(":/qticon16.png"), "16@1x"); - tab->addTab(QIcon(":/qticon16@2x.png"), "16@2x"); - tab->addTab(QIcon(":/qticon16.png"), ""); - tab->addTab(QIcon(":/qticon16@2x.png"), ""); - tab->move(10, 100); - tab->show(); - - auto toolBar = new QToolBar(this); - toolBar->addAction(QIcon(":/qticon16.png"), "16"); - toolBar->addAction(QIcon(":/qticon16@2x.png"), "16@2x"); - toolBar->addAction(QIcon(":/qticon32.png"), "32"); - toolBar->addAction(QIcon(":/qticon32@2x.png"), "32@2x"); - - toolBar->move(10, 200); - toolBar->show(); - } -}; - -class LinePainter : public QWidget -{ -public: - void paintEvent(QPaintEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - -private: - QPoint lastMousePoint; - QList<QPoint> linePoints; -}; - -void LinePainter::paintEvent(QPaintEvent *) -{ - QPainter p(this); - p.fillRect(QRect(QPoint(0, 0), size()), QBrush(Qt::gray)); - - // Default antialiased line - p.setRenderHint(QPainter::Antialiasing); - p.drawLines(linePoints); - - // Cosmetic 1 antialiased line - QPen pen; - pen.setCosmetic(true); - pen.setWidth(1); - p.setPen(pen); - p.translate(3, 3); - p.drawLines(linePoints); - - // Aliased cosmetic 1 line - p.setRenderHint(QPainter::Antialiasing, false); - p.translate(3, 3); - p.drawLines(linePoints); -} - -void LinePainter::mousePressEvent(QMouseEvent *event) -{ - lastMousePoint = event->pos(); -} - -void LinePainter::mouseReleaseEvent(QMouseEvent *) -{ - lastMousePoint = QPoint(); -} - -void LinePainter::mouseMoveEvent(QMouseEvent *event) -{ - if (lastMousePoint.isNull()) - return; - - QPoint newMousePoint = event->pos(); - if (lastMousePoint == newMousePoint) - return; - linePoints.append(lastMousePoint); - linePoints.append(newMousePoint); - lastMousePoint = newMousePoint; - update(); -} - -class CursorTester : public QWidget -{ -public: - CursorTester() = default; - - inline QRect getRect(int idx) const - { - int h = height() / 2; - return QRect(10, 10 + h * (idx - 1), width() - 20, h - 20); - } - - void paintEvent(QPaintEvent *) override - { - QPainter p(this); - QRect r1 = getRect(1); - QRect r2 = getRect(2); - p.fillRect(r1, QColor(200, 200, 250)); - p.drawText(r1, "Drag from here to move a window based on QCursor::pos()"); - p.fillRect(r2, QColor(250, 200, 200)); - p.drawText(r2, "Drag from here to move a window based on mouse event position"); - - if (moving) { - p.setPen(Qt::darkGray); - QFont f = font(); - f.setPointSize(8); - p.setFont(f); - p.drawEllipse(mousePos, 30,60); - QPoint pt = mousePos - QPoint(0, 60); - QPoint pt2 = pt - QPoint(30,10); - QPoint offs(30, 0); - p.drawLine(pt, pt2); - p.drawLine(pt2 - offs, pt2 + offs); - p.drawText(pt2 - offs, "mouse pos"); - - p.setPen(QColor(50,130,70)); - QPoint cursorPos = mapFromGlobal(QCursor::pos()); - pt = cursorPos - QPoint(0, 30); - pt2 = pt + QPoint(60, -20); - p.drawEllipse(cursorPos, 60, 30); - p.drawLine(pt, pt2); - p.drawLine(pt2 - offs, pt2 + offs); - p.drawText(pt2 - offs, "cursor pos"); - } - } - - void mousePressEvent(QMouseEvent *e) override - { - if (moving) - return; - QRect r1 = getRect(1); - QRect r2 = getRect(2); - - moving = r1.contains(e->pos()) || r2.contains(e->pos()); - if (!moving) - return; - useCursorPos = r1.contains(e->pos()); - - if (!moveLabel) - moveLabel = new QLabel(this,Qt::BypassWindowManagerHint|Qt::FramelessWindowHint|Qt::Window ); - - if (useCursorPos) - moveLabel->setText("I'm following QCursor::pos()"); - else - moveLabel->setText("I'm following QMouseEvent::globalPos()"); - moveLabel->adjustSize(); - mouseMoveEvent(e); - moveLabel->show(); - } - - void mouseReleaseEvent(QMouseEvent *) override - { - if (moveLabel) - moveLabel->hide(); - update(); - moving = false; - } - - void mouseMoveEvent(QMouseEvent *e) override - { - if (!moving) - return; - QPoint pos = useCursorPos ? QCursor::pos() : e->globalPos(); - pos -= moveLabel->rect().center(); - moveLabel->move(pos); - mousePos = e->pos(); - update(); - } - -private: - QLabel *moveLabel = nullptr; - QPoint mousePos; - bool useCursorPos = false; - bool moving = false; -}; - -class ScreenDisplayer : public QWidget -{ -public: - ScreenDisplayer() = default; - - void timerEvent(QTimerEvent *) override - { - update(); - } - - void mousePressEvent(QMouseEvent *) override - { - if (!moveLabel) - moveLabel = new QLabel(this,Qt::BypassWindowManagerHint|Qt::FramelessWindowHint|Qt::Window ); - moveLabel->setText("Hello, Qt this is a label\nwith some text"); - moveLabel->show(); - } - - void mouseMoveEvent(QMouseEvent *e) override - { - if (!moveLabel) - return; - moveLabel->move(e->pos() / scaleFactor); - QString str; - QDebug dbg(&str); - dbg.setAutoInsertSpaces(false); - dbg << moveLabel->geometry(); - moveLabel->setText(str); - } - - void mouseReleaseEvent(QMouseEvent *) override - { - if (moveLabel) - moveLabel->hide(); - } - - void showEvent(QShowEvent *) override - { - refreshTimer.start(300, this); - } - - void hideEvent(QHideEvent *) override - { - refreshTimer.stop(); - } - - void paintEvent(QPaintEvent *) override - { - QPainter p(this); - QRectF total; - const auto screens = QGuiApplication::screens(); - for (const QScreen *screen : screens) - total |= screen->geometry(); - if (total.isEmpty()) - return; - - scaleFactor = qMin(width()/total.width(), height()/total.height()); - - p.fillRect(rect(), Qt::black); - p.scale(scaleFactor, scaleFactor); - p.translate(-total.topLeft()); - p.setPen(QPen(Qt::white, 10)); - p.setBrush(Qt::gray); - - for (const QScreen *screen : screens) { - p.drawRect(screen->geometry()); - QFont f = font(); - f.setPixelSize(screen->geometry().height() / 8); - p.setFont(f); - p.drawText(screen->geometry(), Qt::AlignCenter, screen->name()); - } - p.setBrush(QColor(200,220,255,127)); - - const auto topLevels = QApplication::topLevelWidgets(); - for (QWidget *widget : topLevels) { - if (!widget->isHidden()) - p.drawRect(widget->geometry()); - } - - QPolygon cursorShape; - cursorShape << QPoint(0,0) << QPoint(20, 60) - << QPoint(30, 50) << QPoint(60, 80) - << QPoint(80, 60) << QPoint(50, 30) - << QPoint(60, 20); - cursorShape.translate(QCursor::pos()); - p.drawPolygon(cursorShape); - } - -private: - QLabel *moveLabel = nullptr; - qreal scaleFactor = 1; - QBasicTimer refreshTimer; -}; - -class PhysicalSizeTest : public QWidget -{ - Q_OBJECT -public: - PhysicalSizeTest() = default; - - void paintEvent(QPaintEvent *event) override; - - void resizeEvent(QResizeEvent *) override - { - qreal ppi = window()->windowHandle()->screen()->physicalDotsPerInchX(); - QSizeF s = size(); - if (!m_ignoreResize) - m_physicalSize = s / ppi; - } - - bool event(QEvent *event) override - { - if (event->type() == QEvent::ScreenChangeInternal) { - // we will get resize events when the scale factor changes - m_ignoreResize = true; - QTimer::singleShot(100, this, &PhysicalSizeTest::handleScreenChange); - } - return QWidget::event(event); - } - -public slots: - void handleScreenChange() - { - qreal ppi = window()->windowHandle()->screen()->physicalDotsPerInchX(); - QSizeF newSize = m_physicalSize * ppi; - resize(newSize.toSize()); - m_ignoreResize = false; - } - -private: - QSizeF m_physicalSize; - bool m_ignoreResize = false; -}; - -void PhysicalSizeTest::paintEvent(QPaintEvent *) -{ - QPainter p(this); - p.setRenderHint(QPainter::Antialiasing); - - qreal ppi = window()->windowHandle()->screen()->physicalDotsPerInchX(); - qreal ppmm = ppi / 25.4; - qreal h = 15 * ppmm; - QRectF rulerRect(0,0, width(), h); - rulerRect.moveCenter(rect().center()); - - QFont f = font(); - f.setPixelSize(18); - p.setFont(f); - - // draw a rectangle in (Qt) pixel coordinates, for comparison - QRect pixelRect(0, 0, 300, 50); - pixelRect.moveTopLeft(QPoint(5 * ppmm, rulerRect.bottom() + 5 * ppmm)); - p.fillRect(pixelRect, QColor(199,222,255)); - p.drawText(pixelRect, "This rectangle is 300x50 pixels"); - - f.setPixelSize(4 * ppmm); - p.setFont(f); - - QRectF topRect(0, 0, width(), rulerRect.top()); - p.drawText(topRect, Qt::AlignCenter, "The ruler is drawn in physical units.\nThis window tries to keep its physical size\nwhen moved between screens."); - - // draw a ruler in real physical coordinates - - p.fillRect(rulerRect, QColor(255, 222, 111)); - - QPen linePen(Qt::black, 0.3 * ppmm); - p.setPen(linePen); - f.setBold(true); - p.setFont(f); - - qreal vCenter = rulerRect.center().y(); - p.drawLine(0, vCenter, width(), vCenter); - - // cm - for (int i = 0;;) { - i++; - qreal x = i * ppmm; - if (x > width()) - break; - qreal y = rulerRect.bottom(); - qreal len; - if (i % 5) - len = 2 * ppmm; - else if (i % 10) - len = 3 * ppmm; - else - len = h / 2; - - p.drawLine(QPointF(x, y), QPointF(x, y - len)); - if (i % 10 == 5) { - QRectF textR(0, 0, 5 * ppmm, h / 2 - 2 * ppmm); - textR.moveTopLeft(QPointF(x, vCenter)); - int n = i / 10 + 1; - if (n % 10 == 0) - p.setPen(Qt::red); - p.drawText(textR, Qt::AlignCenter, QString::number(n)); - p.setPen(linePen); - } - } - - //inches - for (int i = 0;;) { - i++; - qreal x = i * ppi / 16; - if (x > width()) - break; - qreal y = rulerRect.top(); - - qreal d = h / 10; - qreal len; - if (i % 2) - len = 1 * d; - else if (i % 4) - len = 2 * d; - else if (i % 8) - len = 3 * d; - else if (i % 16) - len = 4 * d; - else - len = h / 2; - - p.drawLine(QPointF(x, y), QPointF(x, y + len)); - if (i % 16 == 12) { - QRectF textR(0, 0, 0.25 * ppi, h / 2 - 2 * d); - textR.moveBottomLeft(QPointF(x, vCenter)); - p.drawText(textR, Qt::AlignCenter, QString::number(1 + i/16)); - } - } - -} - -class GraphicsViewCaching : public QGraphicsView -{ -public: - GraphicsViewCaching() - { - auto scene = new QGraphicsScene(0, 0, 400, 400); - - QGraphicsTextItem *item = scene->addText("NoCache"); - item->setCacheMode(QGraphicsItem::NoCache); - item->setPos(10, 10); - - item = scene->addText("ItemCoordinateCache"); - item->setCacheMode(QGraphicsItem::ItemCoordinateCache); - item->setPos(10, 30); - - item = scene->addText("DeviceCoordinateCache"); - item->setCacheMode(QGraphicsItem::DeviceCoordinateCache); - item->setPos(10, 50); - - setScene(scene); - } -}; - -class MetricsTest : public QTabWidget -{ - Q_OBJECT -public: - MetricsTest() - { - qDebug().noquote().nospace() << "MetricsTest " << QT_VERSION_STR - << ' ' << QGuiApplication::platformName() << '\n' -<< R"(Relevant environment variables are: -QT_FONT_DPI=N -QT_SCALE_FACTOR=n -QT_ENABLE_HIGHDPI_SCALING=0|1 -QT_USE_PHYSICAL_DPI=0|1 -QT_SCREEN_SCALE_FACTORS=N;N;N or QT_SCREEN_SCALE_FACTORS=name:N -QT_SCALE_FACTOR_ROUNDING_POLICY=Round|Ceil|Floor|RoundPreferFloor|PassThrough -QT_DPI_ADJUSTMENT_POLICY=AdjustDpi|DontAdjustDpi|AdjustUpOnly)"; - - m_textEdit = addTextPage("Parameters"); - m_logEdit = addTextPage("Screen Change Log"); - - const auto screens = QGuiApplication::screens(); - for (auto screen : screens) - connectScreenChangeSignals(screen); - connect(qApp, &QGuiApplication::screenAdded, this, &MetricsTest::slotScreenAdded); - connect(qApp, &QGuiApplication::primaryScreenChanged, this, &MetricsTest::slotPrimaryScreenChanged); - connect(qApp, &QGuiApplication::screenRemoved, this, &MetricsTest::slotScreenRemoved); - - setWindowTitle(formatWindowTitle("Screens")); - m_logTimer.start(); - logMessage(briefFormatScreens()); - - // Resize to roughly match the metrics text. - const auto metrics = QFontMetrics(m_textEdit->font(), m_textEdit); - const int width = 10 + metrics.horizontalAdvance(QStringLiteral("X")) * 50; - const int height = 40 + metrics.height() * (10 + 8 * screens.size()); - resize(width, height); - } - - void setVisible(bool visible) override - { - QWidget::setVisible(visible); - if (visible && !m_screenChangedConnected) { - m_screenChangedConnected = true; - QObject::connect(windowHandle(), &QWindow::screenChanged, - this, &MetricsTest::screenChanged); - updateMetrics(); - } - } - - void updateMetrics() - { - QString text; - QTextStream str(&text); - - auto currentScreen = windowHandle()->screen(); - const auto screens = QGuiApplication::screens(); - for (int i = 0, size = screens.size(); i < size; ++i) { - auto screen = screens.at(i); - auto platformScreen = screen->handle(); - str << "Screen #" << i << " \"" << screen->name() << '"'; - if (screen == currentScreen) - str << " [current]"; - if (screen == QGuiApplication::primaryScreen()) - str << " [primary]"; - str << "\n screen geometry: " << screen->geometry() - << "\n platform screen geometry: " << platformScreen->geometry() - << "\n platform screen logicalDpi: " << platformScreen->logicalDpi().first; - -#ifdef HAVE_SCREEN_BASE_DPI - str << "\n platform screen logicalBaseDpi: " << platformScreen->logicalBaseDpi().first; -#endif - str << "\n platform screen devicePixelRatio: " <<platformScreen->devicePixelRatio() - << "\n platform screen physicalDpi: " << screen->physicalDotsPerInch() - << "\n\n"; - } - - str << "widget devicePixelRatio: " << this->devicePixelRatio() - << "\nwidget logicalDpi: " << this->logicalDpiX() - << "\n\nQT_FONT_DPI: " << qgetenv("QT_FONT_DPI") - << "\nQT_SCALE_FACTOR: " << qgetenv("QT_SCALE_FACTOR") - << "\nQT_ENABLE_HIGHDPI_SCALING: " << qgetenv("QT_ENABLE_HIGHDPI_SCALING") - << "\nQT_SCREEN_SCALE_FACTORS: " << qgetenv("QT_SCREEN_SCALE_FACTORS") - << "\nQT_USE_PHYSICAL_DPI: " << qgetenv("QT_USE_PHYSICAL_DPI") - << "\nQT_SCALE_FACTOR_ROUNDING_POLICY: " << qgetenv("QT_SCALE_FACTOR_ROUNDING_POLICY") - << "\nQT_DPI_ADJUSTMENT_POLICY: " << qgetenv("QT_DPI_ADJUSTMENT_POLICY") - << '\n'; - - m_textEdit->setPlainText(text); - } - -private slots: - void screenChanged() - { - const QString message = QLatin1String("screenChanged ") + windowHandle()->screen()->name(); - qInfo("%s", qPrintable(message)); - logMessage(message); - updateMetrics(); - } - - void slotScreenAdded(QScreen *); - void slotScreenRemoved(QScreen *); - void slotPrimaryScreenChanged(QScreen *); - void slotScreenGeometryChanged(const QRect &geometry) - { logScreenChangeSignal(sender(), "geometry", geometry); } - void slotScreenAvailableGeometryChanged(const QRect &geometry) - { logScreenChangeSignal(sender(), "availableGeometry", geometry); } - void slotScreenPhysicalSizeChanged(const QSizeF &size) - { logScreenChangeSignal(sender(), "physicalSize", size); } - void slotScreenPhysicalDotsPerInchChanged(qreal dpi) - { logScreenChangeSignal(sender(), "physicalDotsPerInch", dpi); } - void slotScreenLogicalDotsPerInchChanged(qreal dpi) - { logScreenChangeSignal(sender(), "logicalDotsPerInch", dpi); } - void slotScreenVirtualGeometryChanged(const QRect &rect) - { logScreenChangeSignal(sender(), "virtualGeometry", rect); } - void slotScreenPrimaryOrientationChanged(Qt::ScreenOrientation orientation) - { logScreenChangeSignal(sender(), "primaryOrientation", orientation); } - void slotScreenOrientationChanged(Qt::ScreenOrientation orientation) - { logScreenChangeSignal(sender(), "orientation", orientation); } - void slotScreenRefreshRateChanged(qreal refreshRate) - { logScreenChangeSignal(sender(), "refreshRate", refreshRate); } - -private: - QPlainTextEdit *addTextPage(const QString &title); - void logMessage(const QString &); - void connectScreenChangeSignals(QScreen *s); - static QString briefFormatScreens(); - template <class T> - void logScreenChangeSignal(const QObject *o, const char *name, const T &value); - - QPlainTextEdit *m_textEdit; - QPlainTextEdit *m_logEdit; - QElapsedTimer m_logTimer; - bool m_screenChangedConnected = false; -}; - -void MetricsTest::slotScreenAdded(QScreen *screen) -{ - logMessage(QLatin1String("Added ") + screen->name() + QLatin1Char(' ') - + briefFormatScreens()); - connectScreenChangeSignals(screen); -} - -void MetricsTest::slotScreenRemoved(QScreen *screen) -{ - logMessage(QLatin1String("Removed ") + screen->name() + QLatin1Char(' ') - + briefFormatScreens()); -} - -void MetricsTest::slotPrimaryScreenChanged(QScreen *screen) -{ - logMessage(QLatin1String("PrimaryScreenChanged ") + screen->name() + QLatin1Char(' ') - + briefFormatScreens()); -} - -QPlainTextEdit *MetricsTest::addTextPage(const QString &title) -{ - auto result = new QPlainTextEdit(this); - result->setReadOnly(true); - result->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); - addTab(result, title); - return result; -} - -void MetricsTest::logMessage(const QString &m) -{ - const QString timeStamp = - QStringLiteral("%1ms: %2").arg(m_logTimer.elapsed(), 6, 10, QLatin1Char('0')).arg(m); - m_logEdit->appendPlainText(timeStamp); -} - -void MetricsTest::connectScreenChangeSignals(QScreen *s) -{ - connect(s, &QScreen::geometryChanged, this, &MetricsTest::slotScreenGeometryChanged); - connect(s, &QScreen::availableGeometryChanged, this, &MetricsTest::slotScreenAvailableGeometryChanged); - connect(s, &QScreen::physicalSizeChanged, this, &MetricsTest::slotScreenPhysicalSizeChanged); - connect(s, &QScreen::physicalDotsPerInchChanged, this, &MetricsTest::slotScreenPhysicalDotsPerInchChanged); - connect(s, &QScreen::logicalDotsPerInchChanged, this, &MetricsTest::slotScreenLogicalDotsPerInchChanged); - connect(s, &QScreen::virtualGeometryChanged, this, &MetricsTest::slotScreenVirtualGeometryChanged); - connect(s, &QScreen::primaryOrientationChanged, this, &MetricsTest::slotScreenPrimaryOrientationChanged); - connect(s, &QScreen::orientationChanged, this, &MetricsTest::slotScreenOrientationChanged); - connect(s, &QScreen::refreshRateChanged, this, &MetricsTest::slotScreenRefreshRateChanged); -} - -QString MetricsTest::briefFormatScreens() -{ - QString message; - QTextStream str(&message); - const auto screens = QGuiApplication::screens(); - for (int i = 0, size = screens.size(); i < size; ++i) { - str << (i ? ", " : "("); - str << screens.at(i)->name() << " " << screens.at(i)->geometry(); - } - str << ')'; - return message; -} - -template <class T> -void MetricsTest::logScreenChangeSignal(const QObject *o, const char *name, const T &value) -{ - auto screen = qobject_cast<const QScreen *>(o); - QString message; - QTextStream(&message) << (screen ? screen->name() : QString()) << ' ' << name << " changed: " << value; - logMessage(message); -} - -int main(int argc, char **argv) -{ - qInfo("High DPI tester %s", QT_VERSION_STR); - - QApplication app(argc, argv); - QCoreApplication::setApplicationVersion(QT_VERSION_STR); - - QCommandLineParser parser; - parser.setApplicationDescription("High DPI tester. Pass one or more of the options to\n" - "test various high-dpi aspects. \n" - "--interactive is a special option and opens a configuration" - " window."); - parser.addHelpOption(); - parser.addVersionOption(); - QCommandLineOption controllerOption("interactive", "Show configuration window."); - parser.addOption(controllerOption); - - DemoContainerList demoList; - demoList << new DemoContainer<PixmapPainter>("pixmap", "Test pixmap painter"); - demoList << new DemoContainer<TiledPixmapPainter>("tiledpixmap", "Test tiled pixmap painter"); - demoList << new DemoContainer<Labels>("label", "Test Labels"); - demoList << new DemoContainer<MainWindow>("mainwindow", "Test QMainWindow"); - demoList << new DemoContainer<StandardIcons>("standard-icons", "Test standard icons"); - demoList << new DemoContainer<Caching>("caching", "Test caching"); - demoList << new DemoContainer<Style>("styles", "Test style"); - demoList << new DemoContainer<Fonts>("fonts", "Test fonts"); - demoList << new DemoContainer<IconDrawing>("icondrawing", "Test icon drawing"); - demoList << new DemoContainer<Buttons>("buttons", "Test buttons"); - demoList << new DemoContainer<LinePainter>("linepainter", "Test line painting"); - demoList << new DemoContainer<DragWidget>("draganddrop", "Test drag and drop"); - demoList << new DemoContainer<CursorTester>("cursorpos", "Test cursor and window positioning"); - demoList << new DemoContainer<ScreenDisplayer>("screens", "Test screen and window positioning"); - demoList << new DemoContainer<PhysicalSizeTest>("physicalsize", "Test manual highdpi support using physicalDotsPerInch"); - demoList << new DemoContainer<GraphicsViewCaching>("graphicsview", "Test QGraphicsView caching"); - demoList << new DemoContainer<MetricsTest>("metrics", "Show screen metrics"); - - for (DemoContainerBase *demo : qAsConst(demoList)) - parser.addOption(demo->option()); - - parser.process(app); - - //controller takes ownership of all demos - DemoController controller(demoList, &parser); - - if (parser.isSet(controllerOption) || (QCoreApplication::arguments().count()) <= 1) - controller.show(); - - if (QApplication::topLevelWidgets().isEmpty()) - parser.showHelp(0); - - return app.exec(); -} - -#include "main.moc" |