diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-10-23 00:24:51 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2021-10-26 00:57:36 +0200 |
commit | da632baf34ef2308da04c56c497e115b9d1ad531 (patch) | |
tree | d47e887049c0a7a8e9f35a7fda25186bb6185db7 | |
parent | 0921caf9769c84192c539db22085d343f1a4b5b1 (diff) |
QTabBar: re-layout when tab size hint depends on selected state
QTabBar caches the rects for the tabs to avoid costly recalculation of
each tab's size hint. That cache is only updated via layoutTabs if the
entire tab bar is resized or modified. However, when a style sheet is
set that calculates a different size hint for tabs that are selected,
then the tab bar also needs to be laid-out when the current tab changes.
To minimize the cost, compare the cached size for the new current tab
with its new size hint, and re-layout the tabs when they are different.
Fixes: QTBUG-6905
Fixes: QTBUG-8209
Pick-to: 6.2
Change-Id: I110444d18938c2b3446ee58e4a8c6c472b5f12c3
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
-rw-r--r-- | src/widgets/widgets/qtabbar.cpp | 7 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp | 32 |
2 files changed, 37 insertions, 2 deletions
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 11fa33ca15..8fd5bbfb56 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -1433,6 +1433,13 @@ void QTabBar::setCurrentIndex(int index) int oldIndex = d->currentIndex; if (auto tab = d->at(index)) { d->currentIndex = index; + // If the size hint depends on whether the tab is selected (for instance a style + // sheet rule that sets a bold font on the 'selected' tab) then we need to + // re-layout the entire tab bar. To minimize the cost, do that only if the + // size hint changes for the tab that becomes the current tab (the old curent tab + // will most certainly do the same). QTBUG-6905 + if (tabRect(index).size() != tabSizeHint(index)) + d->layoutTabs(); update(); d->makeVisible(index); if (d->validIndex(oldIndex)) { diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp index 1fe6e7d80e..b1b42c0018 100644 --- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp +++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -105,6 +105,8 @@ private slots: void scrollButtons_data(); void scrollButtons(); + void currentTabLargeFont(); + private: void checkPositions(const TabBar &tabbar, const QList<int> &positions); }; @@ -229,6 +231,7 @@ public: using QTabBar::initStyleOption; using QTabBar::moveTab; using QTabBar::QTabBar; + using QTabBar::tabSizeHint; }; void tst_QTabBar::insertAtCurrentIndex() @@ -933,6 +936,8 @@ void tst_QTabBar::mouseWheel() QVERIFY(tabbar.currentIndex() != startIndex); } +#endif // QT_CONFIG(wheelevent) + void tst_QTabBar::scrollButtons_data() { QTest::addColumn<QTabWidget::TabPosition>("tabPosition"); @@ -999,7 +1004,30 @@ void tst_QTabBar::scrollButtons() QVERIFY(!leftB->isEnabled()); } -#endif // QT_CONFIG(wheelevent) +void tst_QTabBar::currentTabLargeFont() +{ + TabBar tabBar; + tabBar.setStyleSheet(R"( + QTabBar::tab::selected { + font-size: 24pt; + } + )"); + + tabBar.addTab("Tab Item 1"); + tabBar.addTab("Tab Item 2"); + tabBar.addTab("Tab Item 3"); + + tabBar.setCurrentIndex(0); + tabBar.show(); + QVERIFY(QTest::qWaitForWindowExposed(&tabBar)); + + QList<QRect> oldTabRects; + oldTabRects << tabBar.tabRect(0) << tabBar.tabRect(1) << tabBar.tabRect(2); + tabBar.setCurrentIndex(1); + QList<QRect> newTabRects; + newTabRects << tabBar.tabRect(0) << tabBar.tabRect(1) << tabBar.tabRect(2); + QVERIFY(oldTabRects != newTabRects); +} QTEST_MAIN(tst_QTabBar) #include "tst_qtabbar.moc" |