diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp index 7c75be2fc73..73bd466d775 100644 --- a/src/widgets/styles/qstylesheetstyle.cpp +++ b/src/widgets/styles/qstylesheetstyle.cpp @@ -5220,15 +5220,26 @@ QSize QStyleSheetStyle::sizeFromContents(ContentsType ct, const QStyleOption *op #if QT_CONFIG(tabbar) case CT_TabBarTab: { QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab); - if (subRule.hasBox() || !subRule.hasNativeBorder()) { + if (subRule.hasBox() || !subRule.hasNativeBorder() || subRule.hasFont) { int spaceForIcon = 0; bool vertical = false; + QString text; if (const QStyleOptionTab *tab = qstyleoption_cast(opt)) { if (!tab->icon.isNull()) spaceForIcon = 6 /* icon offset */ + 4 /* spacing */ + 2 /* magic */; // ###: hardcoded to match with common style vertical = verticalTabs(tab->shape); + text = tab->text; + } + 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); } - sz = csz + QSize(vertical ? 0 : spaceForIcon, vertical ? spaceForIcon : 0); return subRule.boxSize(subRule.adjustSize(sz)); } sz = subRule.adjustSize(csz); @@ -6058,13 +6069,17 @@ QRect QStyleSheetStyle::subElementRect(SubElement se, const QStyleOption *opt, c case SE_TabBarTabLeftButton: case SE_TabBarTabRightButton: { QRenderRule subRule = renderRule(w, opt, PseudoElement_TabBarTab); - if (subRule.hasBox() || !subRule.hasNativeBorder()) { + if (subRule.hasBox() || !subRule.hasNativeBorder() || subRule.hasFont) { if (se == SE_TabBarTabText) { if (const QStyleOptionTab *tab = qstyleoption_cast(opt)) { const QTabBar *bar = qobject_cast(w); const QRect optRect = bar && tab->tabIndex != -1 ? bar->tabRect(tab->tabIndex) : opt->rect; const QRect r = positionRect(w, subRule, PseudoElement_TabBarTab, optRect, opt->direction); QStyleOptionTab tabCopy(*tab); + if (subRule.hasFont) { + const QFont ruleFont = w ? subRule.font.resolve(w->font()) : subRule.font; + tabCopy.fontMetrics = QFontMetrics(ruleFont); + } tabCopy.rect = subRule.contentsRect(r); return ParentStyle::subElementRect(se, &tabCopy, w); } diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp index f2f9be6bb64..6c4c7d577ba 100644 --- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp +++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp @@ -106,6 +106,8 @@ private slots: #endif void background(); void tabAlignment(); + void tabFont_data(); + void tabFont(); void attributesList(); void minmaxSizes(); void task206238_twice(); @@ -1179,6 +1181,71 @@ void tst_QStyleSheetStyle::tabAlignment() QVERIFY(bar->geometry().top() > 100); } +void tst_QStyleSheetStyle::tabFont_data() +{ + QTest::addColumn("pixelSize"); + QTest::addColumn("tabPosition"); + + QTest::newRow("medium, horizontal") << 24 << QTabWidget::North; + QTest::newRow("large, vertical") << 36 << QTabWidget::West; +} + +#include + +void tst_QStyleSheetStyle::tabFont() +{ + QFETCH(int, pixelSize); + QFETCH(QTabWidget::TabPosition, tabPosition); + const bool vertical = tabPosition == QTabWidget::West || tabPosition == QTabWidget::East; + + // macOS style centers tabs and messes up the test + QWindowsStyle windowsStyle; + QWidget topLevel; + topLevel.setStyle(&windowsStyle); + topLevel.setWindowTitle(QTest::currentTestFunction()); + QTabWidget tabWidget; + tabWidget.setStyle(&windowsStyle); + tabWidget.addTab(new QWidget,"Tab title"); + tabWidget.setTabPosition(tabPosition); + QTabWidget styledWidget; + styledWidget.setStyle(&windowsStyle); + styledWidget.setTabPosition(tabPosition); + styledWidget.addTab(new QWidget,"Tab title"); + + QTabBar *bar = tabWidget.tabBar(); + QTabBar *styledBar = styledWidget.tabBar(); + QVERIFY(bar && styledBar); + bar->setStyle(&windowsStyle); + styledBar->setStyle(&windowsStyle); + + QBoxLayout box(vertical ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom); + box.addWidget(&tabWidget); + box.addWidget(&styledWidget); + topLevel.setLayout(&box); + + topLevel.resize(600, 600); + centerOnScreen(&topLevel); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + + const QRect defaultRect = bar->tabRect(0); + QCOMPARE(styledBar->tabRect(0), defaultRect); + + QFont font; + font.setPointSize(pixelSize); + tabWidget.setFont(font); + + 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)); + const QRect rectWithStyle = styledBar->tabRect(0); + QCOMPARE(rectWithStyle.size(), rectWithFont.size()); +} + void tst_QStyleSheetStyle::attributesList() { const QColor blue(Qt::blue);