From 778805a66f0228b407027bf400d7b0e3ba81c47f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20De=20Canni=C3=A8re?= Date: Fri, 6 Jun 2025 15:20:47 +0200 Subject: [PATCH] Widgets: Set viewItemPosition style option for QTableView and QListView Before this patch, we did not set the view item positions in the views. This was fine as they were ignored until b780eaf6a063a7efe03417cf6b7008a188e222a4 added a condition to early exit on invalid positions. This then broke all qss background styling using QStyleOptionViewItem::ViewItemPosition as they were always invalid. Set the position when trying to draw a cell of the view before reaching the code handling the qss rules for backgrounds. Fixes: QTBUG-137346 Pick-to: 6.8 Change-Id: I83d7a3ea7b9bab98889791bb807988a74e355b93 Reviewed-by: Santhosh Kumar (cherry picked from commit 5aa1bc46217dc6f53fde8fe17608cf0e5f7a5e78) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit da9ac3bf1d2c2d7259563918f5e665d421957ec5) --- src/widgets/itemviews/qlistview.cpp | 1 + src/widgets/itemviews/qtableview.cpp | 20 ++++++++++ src/widgets/itemviews/qtableview_p.h | 2 + .../stylesheet/qss/qlistview/background.qss | 3 ++ .../stylesheet/qss/qtableview/background.qss | 9 +++++ .../stylesheet/tst_baseline_stylesheet.cpp | 38 +++++++++++++++++++ 6 files changed, 73 insertions(+) create mode 100644 tests/baseline/stylesheet/qss/qlistview/background.qss create mode 100644 tests/baseline/stylesheet/qss/qtableview/background.qss diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 67e72c38c6c..5cd4addf784 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -980,6 +980,7 @@ void QListView::initViewItemOption(QStyleOptionViewItem *option) const if (d->gridSize().isValid()) { option->rect.setSize(d->gridSize()); } + option->viewItemPosition = QStyleOptionViewItem::OnlyOne; } diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index 89075a6de11..f656b9921ee 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -1022,6 +1022,25 @@ void QTableViewPrivate::sortIndicatorChanged(int column, Qt::SortOrder order) model->sort(column, order); } +QStyleOptionViewItem::ViewItemPosition QTableViewPrivate::viewItemPosition( + const QModelIndex &index) const +{ + int visualColumn = horizontalHeader->visualIndex(index.column()); + int count = horizontalHeader->count(); + + if (count <= 0 || visualColumn < 0 || visualColumn >= count) + return QStyleOptionViewItem::Invalid; + + if (count == 1 && visualColumn == 0) + return QStyleOptionViewItem::OnlyOne; + else if (visualColumn == 0) + return QStyleOptionViewItem::Beginning; + else if (visualColumn == count - 1) + return QStyleOptionViewItem::End; + else + return QStyleOptionViewItem::Middle; +} + /*! \internal Draws a table cell. @@ -1045,6 +1064,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItem & } opt.palette.setCurrentColorGroup(cg); } + opt.viewItemPosition = viewItemPosition(index); if (index == q->currentIndex()) { const bool focus = (q->hasFocus() || viewport->hasFocus()) && q->currentIndex().isValid(); diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h index 30f82af64c3..13922d9fd44 100644 --- a/src/widgets/itemviews/qtableview_p.h +++ b/src/widgets/itemviews/qtableview_p.h @@ -138,6 +138,8 @@ public: return horizontalHeader->logicalIndex(visualCol); } + QStyleOptionViewItem::ViewItemPosition viewItemPosition(const QModelIndex &index) const; + inline int accessibleTable2Index(const QModelIndex &index) const { const int vHeader = verticalHeader ? 1 : 0; return (index.row() + (horizontalHeader ? 1 : 0)) * (index.model()->columnCount() + vHeader) diff --git a/tests/baseline/stylesheet/qss/qlistview/background.qss b/tests/baseline/stylesheet/qss/qlistview/background.qss new file mode 100644 index 00000000000..d73a91a6e9b --- /dev/null +++ b/tests/baseline/stylesheet/qss/qlistview/background.qss @@ -0,0 +1,3 @@ +QAbstractItemView::item:only-one{ + background-color: red; +} diff --git a/tests/baseline/stylesheet/qss/qtableview/background.qss b/tests/baseline/stylesheet/qss/qtableview/background.qss new file mode 100644 index 00000000000..bce159eb7d0 --- /dev/null +++ b/tests/baseline/stylesheet/qss/qtableview/background.qss @@ -0,0 +1,9 @@ +QAbstractItemView::item:first{ + background-color: green; +} +QAbstractItemView::item:middle { + background-color: yellow; +} +QAbstractItemView::item:last { + background-color: red; +} diff --git a/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp b/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp index ea837089ddc..172a2ad7f64 100644 --- a/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp +++ b/tests/baseline/stylesheet/tst_baseline_stylesheet.cpp @@ -30,6 +30,12 @@ private slots: void tst_QHeaderView_data(); void tst_QHeaderView(); + void tst_QTableView_data(); + void tst_QTableView(); + + void tst_QListView_data(); + void tst_QListView(); + private: QDir styleSheetDir; }; @@ -227,6 +233,38 @@ void tst_Stylesheet::tst_QHeaderView() QBASELINE_TEST(takeSnapshot()); } +void tst_Stylesheet::tst_QTableView_data() +{ + loadTestFiles(); +} + +void tst_Stylesheet::tst_QTableView() +{ + QHBoxLayout *layout = new QHBoxLayout; + QTableWidget *tw = new QTableWidget(2, 3); + layout->addWidget(tw); + testWindow()->setLayout(layout); + makeVisible(); + QBASELINE_TEST(takeSnapshot()); +} + +void tst_Stylesheet::tst_QListView_data() +{ + loadTestFiles(); +} + +void tst_Stylesheet::tst_QListView() +{ + QStringListModel m({ "Berlin", "Paris", "London" }); + QListView *v = new QListView; + v->setModel(&m); + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(v); + testWindow()->setLayout(layout); + makeVisible(); + QBASELINE_TEST(takeSnapshot()); +} + QBASELINETEST_MAIN(tst_Stylesheet) #include "tst_baseline_stylesheet.moc"