diff options
Diffstat (limited to 'tests/auto/widgets/styles/qstylesheetstyle')
-rw-r--r-- | tests/auto/widgets/styles/qstylesheetstyle/CMakeLists.txt | 38 | ||||
-rw-r--r-- | tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp | 335 |
2 files changed, 287 insertions, 86 deletions
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/CMakeLists.txt b/tests/auto/widgets/styles/qstylesheetstyle/CMakeLists.txt index bf4e52862c..6543ec9961 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/CMakeLists.txt +++ b/tests/auto/widgets/styles/qstylesheetstyle/CMakeLists.txt @@ -1,37 +1,33 @@ -# Generated from qstylesheetstyle.pro. - -if(NOT QT_FEATURE_private_tests) - return() -endif() +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## tst_qstylesheetstyle Test: ##################################################################### +if(NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT) + cmake_minimum_required(VERSION 3.16) + project(tst_qstylesheetstyle LANGUAGES CXX) + find_package(Qt6BuildInternals REQUIRED COMPONENTS STANDALONE_TEST) +endif() + +# Resources: +set(resources_resource_files + "images/testimage.png" + "images/testimage@2x.png" +) + qt_internal_add_test(tst_qstylesheetstyle SOURCES tst_qstylesheetstyle.cpp - PUBLIC_LIBRARIES + LIBRARIES Qt::Gui Qt::GuiPrivate Qt::TestPrivate Qt::Widgets Qt::WidgetsPrivate + TESTDATA ${resources_resource_files} + BUILTIN_TESTDATA ) -# Resources: -set(resources_resource_files - "images/testimage.png" - "images/testimage@2x.png" -) - -qt_internal_add_resource(tst_qstylesheetstyle "resources" - PREFIX - "/" - FILES - ${resources_resource_files} -) - - -#### Keys ignored in scope 1:.:.:qstylesheetstyle.pro:<TRUE>: # _REQUIREMENTS = "qtConfig(private_tests)" diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 27500173c8..a9a1817b8a 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -1,30 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2019 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$ -** -****************************************************************************/ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #include <QtWidgets/QApplication> #include <QtWidgets/QCheckBox> @@ -63,6 +38,8 @@ #include <private/qstylesheetstyle_p.h> #include <private/qhighdpiscaling_p.h> #include <QtTest/private/qtesthelpers_p.h> +#include <qpa/qplatformtheme.h> +#include <QtWidgets/private/qapplication_p.h> using namespace QTestPrivate; @@ -77,6 +54,7 @@ private slots: void cleanup(); void repolish(); void repolish_without_crashing(); + void repolish_children(); void numinstances(); void widgetsBeforeAppStyleSheet(); void widgetsAfterAppStyleSheet(); @@ -116,6 +94,7 @@ private slots: void proxyStyle(); void dialogButtonBox(); void emptyStyleSheet(); + void toolTip_data(); void toolTip(); void embeddedFonts(); void opaquePaintEvent_data(); @@ -128,6 +107,9 @@ private slots: void QTBUG36933_brokenPseudoClassLookup(); void styleSheetChangeBeforePolish(); void placeholderColor(); + void accent(); + void enumPropertySelector_data(); + void enumPropertySelector(); //at the end because it mess with the style. void widgetStyle(); void appStyle(); @@ -138,6 +120,11 @@ private slots: void highdpiImages_data(); void highdpiImages(); + void iconSizes_data(); + void iconSizes(); + void inheritWidgetPalette_data(); + void inheritWidgetPalette(); + private: static QColor COLOR(const QWidget &w) { @@ -438,6 +425,19 @@ void tst_QStyleSheetStyle::repolish_without_crashing() QCOMPARE(COLOR(*label), QColor(Qt::red)); } +void tst_QStyleSheetStyle::repolish_children() +{ + QWidget parent; + parent.setStyleSheet("QPushButton { color: red; background: white }"); + QPushButton p2(&parent); + // a layout would call show, triggering a polish of the child while + // the parent on which the style sheet is set remains unpolished + p2.show(); + QCOMPARE(BACKGROUND(p2), Qt::white); + parent.setStyleSheet("QPushButton { color: red; background: red }"); + QCOMPARE(BACKGROUND(p2), Qt::red); +} + void tst_QStyleSheetStyle::widgetStyle() { qApp->setStyleSheet(QString()); @@ -965,7 +965,7 @@ void tst_QStyleSheetStyle::focusColors() // ten pixels of the right color requires quite a many characters, as the // majority of the pixels will have slightly different colors due to the // anti-aliasing effect. -#if !defined(Q_OS_WIN32) && !(defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(Q_CC_INTEL)) +#if !defined(Q_OS_WIN32) && !(defined(Q_OS_LINUX) && defined(Q_CC_GNU)) QSKIP("This is a fragile test which fails on many esoteric platforms because of focus problems" " (for example, QTBUG-33959)." "That doesn't mean that the feature doesn't work in practice."); @@ -980,7 +980,6 @@ void tst_QStyleSheetStyle::focusColors() centerOnScreen(&frame); frame.show(); - QApplication::setActiveWindow(&frame); QVERIFY(QTest::qWaitForWindowActive(&frame)); for (QWidget *widget : frame.widgets()) { @@ -1026,7 +1025,6 @@ void tst_QStyleSheetStyle::hoverColors() QCursor::setPos(frame.geometry().topLeft() - QPoint(100, 0)); frame.show(); - QApplication::setActiveWindow(&frame); QVERIFY(QTest::qWaitForWindowActive(&frame)); QWindow *frameWindow = frame.windowHandle(); @@ -1201,20 +1199,31 @@ void tst_QStyleSheetStyle::tabAlignment() void tst_QStyleSheetStyle::tabFont_data() { - QTest::addColumn<int>("pixelSize"); + QTest::addColumn<QFont>("tabFont"); QTest::addColumn<QTabWidget::TabPosition>("tabPosition"); - - QTest::newRow("medium, horizontal") << 24 << QTabWidget::North; - QTest::newRow("large, vertical") << 36 << QTabWidget::West; + QTest::addColumn<bool>("closable"); + + QFont medium; + medium.setPixelSize(24); + QFont large; + large.setPixelSize(36); + QFont bold; + bold.setBold(true); + + QTest::newRow("medium, horizontal") << medium << QTabWidget::North << false; + QTest::newRow("large, vertical") << large << QTabWidget::West << false; + QTest::newRow("bold, horizontal, closable") << bold << QTabWidget::North << true; + QTest::newRow("bold, vertical, closable") << bold << QTabWidget::West << true; } -#include <QApplication> - void tst_QStyleSheetStyle::tabFont() { - QFETCH(int, pixelSize); + QFETCH(QFont, tabFont); QFETCH(QTabWidget::TabPosition, tabPosition); + QFETCH(bool, closable); const bool vertical = tabPosition == QTabWidget::West || tabPosition == QTabWidget::East; + const QString tab0Text("Tab title"); + const QString tab1Text("Very Long Tab title"); // macOS style centers tabs and messes up the test QWindowsStyle windowsStyle; @@ -1223,18 +1232,22 @@ void tst_QStyleSheetStyle::tabFont() topLevel.setWindowTitle(QTest::currentTestFunction()); QTabWidget tabWidget; tabWidget.setStyle(&windowsStyle); - tabWidget.addTab(new QWidget,"Tab title"); tabWidget.setTabPosition(tabPosition); + tabWidget.addTab(new QWidget, tab0Text); + tabWidget.addTab(new QWidget, tab1Text); QTabWidget styledWidget; styledWidget.setStyle(&windowsStyle); styledWidget.setTabPosition(tabPosition); - styledWidget.addTab(new QWidget,"Tab title"); + styledWidget.addTab(new QWidget, tab0Text); + styledWidget.addTab(new QWidget, tab1Text); QTabBar *bar = tabWidget.tabBar(); QTabBar *styledBar = styledWidget.tabBar(); QVERIFY(bar && styledBar); bar->setStyle(&windowsStyle); + bar->setTabsClosable(closable); styledBar->setStyle(&windowsStyle); + styledBar->setTabsClosable(closable); QBoxLayout box(vertical ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom); box.addWidget(&tabWidget); @@ -1246,22 +1259,36 @@ void tst_QStyleSheetStyle::tabFont() topLevel.show(); QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + const QFont defaultFont = tabWidget.font(); + if (QFontMetrics(defaultFont).size(Qt::TextShowMnemonic, tab0Text).width() >= + QFontMetrics(tabFont).size(Qt::TextShowMnemonic, tab0Text).width()) { + QSKIP("The used font is not larger when bold"); + } + const QRect defaultRect = bar->tabRect(0); QCOMPARE(styledBar->tabRect(0), defaultRect); - QFont font; - font.setPointSize(pixelSize); - tabWidget.setFont(font); - + tabWidget.setFont(tabFont); const QRect rectWithFont = bar->tabRect(0); if (vertical) QVERIFY(rectWithFont.height() > defaultRect.height()); else QVERIFY(rectWithFont.width() > defaultRect.width()); - styledWidget.setStyleSheet(QString("QTabBar { font-size: %1pt; }").arg(pixelSize)); + QString styleSheet = "QTabBar::tab:first {"; + if (tabFont.pixelSize() != -1) + styleSheet += QString(" font-size: %1px;").arg(tabFont.pixelSize()); + if (tabFont.bold()) + styleSheet += " font-weight: bold;"; + styleSheet += "}"; + + styledWidget.setStyleSheet(styleSheet); const QRect rectWithStyle = styledBar->tabRect(0); - QCOMPARE(rectWithStyle.size(), rectWithFont.size()); + + if (vertical) + QCOMPARE(rectWithStyle.height(), rectWithFont.height()); + else + QCOMPARE(rectWithStyle.width(), rectWithFont.width()); } void tst_QStyleSheetStyle::attributesList() @@ -1630,19 +1657,32 @@ private: const QString m_oldStyleName; }; +void tst_QStyleSheetStyle::toolTip_data() +{ + QTest::addColumn<QString>("style"); + + QTest::newRow("fusion") << QString("Fusion"); +#ifdef Q_OS_WINDOWS + QTest::newRow("windowsvista") << QString("WindowsVista"); +#endif +} + void tst_QStyleSheetStyle::toolTip() { + QFETCH(QString, style); + if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) QSKIP("Wayland: This fails. Figure out why."); - qApp->setStyleSheet(QString()); QWidget w; w.resize(m_testSize); w.setWindowTitle(QTest::currentTestFunction()); + // Use "Fusion" to prevent the Vista style from clobbering the tooltip palette in polish(). - QStyle *fusionStyle = QStyleFactory::create(QLatin1String("Fusion")); - QVERIFY(fusionStyle); - ApplicationStyleSetter as(fusionStyle); + QStyle *appStyle = QStyleFactory::create(style); + QVERIFY(appStyle); + ApplicationStyleSetter as(appStyle); + QHBoxLayout layout(&w); w.setLayout(&layout); @@ -1670,37 +1710,65 @@ void tst_QStyleSheetStyle::toolTip() wid4->setToolTip("this is wid4"); wid4->setObjectName("wid4"); + QWidget *wid5 = new QPushButton("wid5", &w); + layout.addWidget(wid5); + wid5->setStyleSheet("QToolTip { background: #ff0; color: #f00 }"); + wid5->setToolTip("this is wid5"); + wid5->setObjectName("wid5"); + centerOnScreen(&w); w.show(); - QApplication::setActiveWindow(&w); QVERIFY(QTest::qWaitForWindowActive(&w)); - const QColor normalToolTip = QToolTip::palette().color(QPalette::Inactive, QPalette::ToolTipBase); + QColor normalToolTipBgColor = QToolTip::palette().color(QPalette::Inactive, QPalette::ToolTipBase); + +#ifdef Q_OS_MACOS + // macOS uses tool tip text color set in label palette + const QPalette *labelPalette = QGuiApplicationPrivate::platformTheme()->palette(QPlatformTheme::LabelPalette); + QColor normalToolTipFgColor = labelPalette->color(QPalette::Inactive, QPalette::ToolTipText); +#else + QColor normalToolTipFgColor = QToolTip::palette().color(QPalette::Inactive, QPalette::ToolTipText); +#endif + // Tooltip on the widget without stylesheet, then to other widget, // including one without stylesheet (the tooltip will be reused, // but its color must change) - const QWidgetList widgets{wid4, wid1, wid2, wid3, wid4}; - const QList<QColor> colors { normalToolTip, QColor("#ae2"), QColor("#f81"), QColor("#0b8"), - normalToolTip }; + const QWidgetList widgets{wid4, wid1, wid2, wid3, wid4, wid5}; + const QList<QColor> bgcolors { normalToolTipBgColor, QColor("#ae2"), QColor("#f81"), + QColor("#0b8"), normalToolTipBgColor, QColor("#ff0")}; + const QList<QColor> fgcolors { normalToolTipFgColor, normalToolTipFgColor, normalToolTipFgColor, + normalToolTipFgColor, normalToolTipFgColor, QColor("#f00")}; QWidgetList topLevels; - for (int i = 0; i < widgets.count() ; ++i) { + for (int i = 0; i < widgets.size() ; ++i) { QWidget *wid = widgets.at(i); - QColor col = colors.at(i); + QColor bgColor = bgcolors.at(i); + QColor fgColor = fgcolors.at(i); QToolTip::showText( QPoint(0,0) , "This is " + wid->objectName(), wid); topLevels = QApplication::topLevelWidgets(); QWidget *tooltip = nullptr; - for (QWidget *widget : qAsConst(topLevels)) { + for (QWidget *widget : std::as_const(topLevels)) { if (widget->inherits("QTipLabel")) { tooltip = widget; break; } } + QVERIFY(tooltip); QTRY_VERIFY(tooltip->isVisible()); // Wait until Roll-Effect is finished (Windows Vista) - QCOMPARE(tooltip->palette().color(tooltip->backgroundRole()), col); + +#ifdef Q_OS_WINDOWS + // If tooltip palette contains empty resolve mask, validate with inherited palette + if (!tooltip->palette().resolveMask()) { + bgColor = w.palette().color(tooltip->backgroundRole()); + fgColor = w.palette().color(tooltip->foregroundRole()); + } +#endif + + QCOMPARE(tooltip->palette().color(tooltip->backgroundRole()), bgColor); + QCOMPARE(tooltip->palette().color(tooltip->foregroundRole()), fgColor); } QToolTip::showText( QPoint(0,0) , "This is " + wid3->objectName(), wid3); @@ -1708,7 +1776,7 @@ void tst_QStyleSheetStyle::toolTip() delete wid3; //should not crash; QTest::qWait(10); topLevels = QApplication::topLevelWidgets(); - for (QWidget *widget : qAsConst(topLevels)) + for (QWidget *widget : std::as_const(topLevels)) widget->update(); //should not crash either } @@ -1818,7 +1886,6 @@ void tst_QStyleSheetStyle::complexWidgetFocus() centerOnScreen(&frame); frame.show(); - QApplication::setActiveWindow(&frame); QVERIFY(QTest::qWaitForWindowActive(&frame)); for (QWidget *widget : widgets) { widget->setFocus(); @@ -1907,7 +1974,6 @@ void tst_QStyleSheetStyle::task232085_spinBoxLineEditBg() centerOnScreen(&frame); frame.show(); - QApplication::setActiveWindow(&frame); spinbox->setFocus(); QVERIFY(QTest::qWaitForWindowActive(&frame)); @@ -2043,7 +2109,6 @@ void tst_QStyleSheetStyle::QTBUG36933_brokenPseudoClassLookup() QVERIFY(QTest::qWaitForWindowExposed(&widget)); widget.activateWindow(); - QApplication::setActiveWindow(&widget); QVERIFY(QTest::qWaitForWindowActive(&widget)); QHeaderView *verticalHeader = widget.verticalHeader(); @@ -2316,11 +2381,151 @@ void tst_QStyleSheetStyle::placeholderColor() QLineEdit le2; le2.setEnabled(false); le1.ensurePolished(); - QCOMPARE(le1.palette().placeholderText(), red); + QColor phColor = le1.palette().placeholderText().color(); + QCOMPARE(phColor.rgb(), red.rgb()); + QVERIFY(phColor.alpha() < red.alpha()); + le2.ensurePolished(); - QCOMPARE(le2.palette().placeholderText(), red); + phColor = le2.palette().placeholderText().color(); + QCOMPARE(phColor.rgb(), red.rgb()); + QVERIFY(phColor.alpha() < red.alpha()); + le2.setEnabled(true); - QCOMPARE(le2.palette().placeholderText(), red); + phColor = le2.palette().placeholderText().color(); + QCOMPARE(phColor.rgb(), red.rgb()); + QVERIFY(phColor.alpha() < red.alpha()); + + const char *phSpec = "#aabbccdd"; + le1.setStyleSheet(QString("QLineEdit { placeholder-text-color: %1; }").arg(phSpec)); + QCOMPARE(le1.palette().placeholderText().color(), QColor(phSpec)); +} + +void tst_QStyleSheetStyle::accent() +{ + QLineEdit lineEdit; + const QColor universe(42, 42, 42); + lineEdit.setStyleSheet(QString("QLineEdit { accent-color: %1; }").arg(universe.name())); + lineEdit.ensurePolished(); + QCOMPARE(lineEdit.palette().accent().color(), universe); +} + +void tst_QStyleSheetStyle::enumPropertySelector_data() +{ + QTest::addColumn<QString>("styleSheet"); + + QTest::addRow("Enum value") << R"(QToolButton[popupMode=MenuButtonPopup] { padding-right: 40px; })"; + QTest::addRow("Int value") << R"(QToolButton[popupMode="1"] { padding-right: 40px; })"; +} + +void tst_QStyleSheetStyle::enumPropertySelector() +{ + QFETCH(QString, styleSheet); + + QToolButton button; + QMenu menu; + menu.addAction("Action1"); + QPixmap pm(50, 50); + pm.fill(Qt::red); + button.setIcon(pm); + button.setMenu(&menu); + button.setPopupMode(QToolButton::MenuButtonPopup); + + button.show(); + const QSize unstyledSizeHint = button.sizeHint(); + + qApp->setStyleSheet(styleSheet); + const QSize styledSizeHint = button.sizeHint(); + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QEXPECT_FAIL("Enum value", "In Qt 5, style sheet selectors have to use integer enum values", Continue); +#endif + + QVERIFY(styledSizeHint.width() > unstyledSizeHint.width()); +} + +void tst_QStyleSheetStyle::iconSizes_data() +{ + QTest::addColumn<QString>("styleSheet"); + QTest::addColumn<QFont>("font"); + QTest::addColumn<QSize>("iconSize"); + + const int defaultSize = QApplication::style()->pixelMetric(QStyle::PM_ButtonIconSize); + + QFont smallFont; + smallFont.setPointSizeF(9.0); + QFont largeFont; + largeFont.setPointSizeF(24.0); + QFont hugeFont; + hugeFont.setPointSizeF(40.0); + + QTest::addRow("default") << QString() << QFont() << QSize(defaultSize, defaultSize); + QTest::addRow("pixels") << "icon-size: 50px" << QFont() << QSize(50, 50); + QTest::addRow("points") << "icon-size: 20pt" << QFont() << QSize(15, 15); + QTest::addRow("pixels with font") << "icon-size: 50px" << smallFont << QSize(50, 50); + QTest::addRow("points with font") << "icon-size: 20pt" << largeFont << QSize(15, 15); + + const QFontMetrics defaultMetrics{QFont()}; + const QFontMetrics smallMetrics(smallFont); + const QFontMetrics largeMetrics(largeFont); + const QFontMetrics hugeMetrics(hugeFont); + QTest::addRow("1em, default font") << "icon-size: 1em" + << QFont() << QSize(defaultMetrics.height(), defaultMetrics.height()); + QTest::addRow("1em, small font") << "icon-size: 1em" + << smallFont << QSize(smallMetrics.height(), smallMetrics.height()); + QTest::addRow("1em, large font") << "icon-size: 1em" + << largeFont << QSize(largeMetrics.height(), largeMetrics.height()); + QTest::addRow("1.5em, lage font") << "icon-size: 1.5em" + << largeFont << QSize(largeMetrics.height(), largeMetrics.height()) * 1.5; + QTest::addRow("2em with styled font") << "font-size: 40pt; icon-size: 2em" + << QFont() << QSize(hugeMetrics.height(), hugeMetrics.height()) * 2; + + QTest::addRow("1ex, default font") << "icon-size: 1ex" + << QFont() << QSize(defaultMetrics.xHeight(), defaultMetrics.xHeight()); + QTest::addRow("1ex, small font") << "icon-size: 1ex" + << smallFont << QSize(smallMetrics.xHeight(), smallMetrics.xHeight()); + QTest::addRow("1ex, large font") << "icon-size: 1ex" + << largeFont << QSize(largeMetrics.xHeight(), largeMetrics.xHeight()); + QTest::addRow("1.5ex, lage font") << "icon-size: 1.5ex" + << largeFont << QSize(largeMetrics.xHeight(), largeMetrics.xHeight()) * 1.5; + QTest::addRow("2ex with styled font") << "font-size: 40pt; icon-size: 2ex" + << QFont() << QSize(hugeMetrics.xHeight(), hugeMetrics.xHeight()) * 2; +} + +void tst_QStyleSheetStyle::iconSizes() +{ + QFETCH(QString, styleSheet); + QFETCH(QFont, font); + QFETCH(QSize, iconSize); + + QPushButton button; + button.setFont(font); + button.setStyleSheet(styleSheet); + QCOMPARE(button.iconSize(), iconSize); +} + +void tst_QStyleSheetStyle::inheritWidgetPalette_data() +{ + QTest::addColumn<const QString>("styleSheet"); + QTest::addColumn<const QColor>("phColorPalette"); + + QTest::addRow("blueAndGreen") << "QLineEdit {color: rgb(0,0,255);}" << QColor(Qt::green); + QTest::addRow("emptyStyleSheet") << QString() << QColor(Qt::green); + +} + +void tst_QStyleSheetStyle::inheritWidgetPalette() +{ + QFETCH(const QString, styleSheet); + QFETCH(const QColor, phColorPalette); + + QLineEdit edit; + QPalette palette = edit.palette(); + palette.setBrush(QPalette::PlaceholderText, phColorPalette); + edit.setPalette(palette); + edit.setStyleSheet(styleSheet); + const QColor phColor = edit.palette().placeholderText().color(); + + QCOMPARE(phColor, phColorPalette); } QTEST_MAIN(tst_QStyleSheetStyle) |