diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index b7999489338..3ad68067afd 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -5414,13 +5414,25 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op if (subRule.hasBox() || !subRule.hasNativeBorder()) sz = csz + QSize(vertical ? 0 : spaceForIcon, vertical ? spaceForIcon : 0); if (subRule.hasFont) { - QFont ruleFont = subRule.font.resolve(w->font()); - QFontMetrics fm(ruleFont); - const QSize textSize = fm.size(Qt::TextShowMnemonic, text) - + QSize(pixelMetric(PM_TabBarTabHSpace, opt, w), - pixelMetric(PM_TabBarTabVSpace, opt, w)); - sz = sz.expandedTo(vertical ? textSize.transposed() : textSize); + // first we remove the space needed for the text using the default font + const QSize oldTextSize = opt->fontMetrics.size(Qt::TextShowMnemonic, text); + (vertical ? sz.rheight() : sz.rwidth()) -= oldTextSize.width(); + + // then we add the space needed when using the rule font to the relevant + // dimension, and constraint the other dimension to the maximum to make + // sure we don't grow, but also don't clip icons or buttons. + const QFont ruleFont = subRule.font.resolve(w->font()); + const QFontMetrics fm(ruleFont); + const QSize textSize = fm.size(Qt::TextShowMnemonic, text); + if (vertical) { + sz.rheight() += textSize.width(); + sz.rwidth() = qMax(textSize.height(), sz.width()); + } else { + sz.rwidth() += textSize.width(); + sz.rheight() = qMax(textSize.height(), sz.height()); + } } + return subRule.boxSize(subRule.adjustSize(sz)); } sz = subRule.adjustSize(csz); diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index 492b206019a..ac67d9e6bdd 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -1220,20 +1220,31 @@ void tst_QStyleSheetStyle::tabAlignment() void tst_QStyleSheetStyle::tabFont_data() { - QTest::addColumn("pixelSize"); + QTest::addColumn("tabFont"); QTest::addColumn("tabPosition"); + QTest::addColumn("closable"); - QTest::newRow("medium, horizontal") << 24 << QTabWidget::North; - QTest::newRow("large, vertical") << 36 << QTabWidget::West; + 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 - 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; @@ -1242,18 +1253,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); @@ -1265,22 +1280,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()