diff options
| -rw-r--r-- | src/quick/doc/snippets/qml/tableview/overlay.qml | 46 | ||||
| -rw-r--r-- | src/quick/items/qquicktableview.cpp | 36 | ||||
| -rw-r--r-- | src/quick/items/qquicktableview_p.h | 1 | ||||
| -rw-r--r-- | tests/auto/quick/qquicktableview/tst_qquicktableview.cpp | 47 |
4 files changed, 130 insertions, 0 deletions
diff --git a/src/quick/doc/snippets/qml/tableview/overlay.qml b/src/quick/doc/snippets/qml/tableview/overlay.qml new file mode 100644 index 0000000000..b79e457f81 --- /dev/null +++ b/src/quick/doc/snippets/qml/tableview/overlay.qml @@ -0,0 +1,46 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Window + +Window { + width: 480 + height: 640 + visible: true + visibility: Window.AutomaticVisibility + + TableView { + id: tableView + anchors.fill: parent + clip: true + } + + //![0] + Rectangle { + id: overlay + width: 20 + height: 20 + radius: 10 + color: "blue" + + z: 10 + parent: tableView.contentItem + + Connections { + target: tableView + function onLayoutChanged() { + let item = tableView.itemAtCell(5, 5) + let insideViewport = item !== null + + overlay.visible = insideViewport + if (insideViewport) { + overlay.x = item.x + overlay.y = item.y + } + } + } + } + //![0] + +} diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp index 38807ba0b3..314408e357 100644 --- a/src/quick/items/qquicktableview.cpp +++ b/src/quick/items/qquicktableview.cpp @@ -194,6 +194,19 @@ \snippet qml/tableview/tableviewwithheader.qml 0 + Here is another example that shows how to create an overlay item that + stays on top of a particular cell. This requires a bit more code, since + the location of a cell will \l {layoutChanged}{change} if the user, for + example, is resizing a column in front of it. + + \snippet qml/tableview/overlay.qml 0 + + You could also parent the overlay directly to the cell instead of the + \l contentItem. But doing so will be fragile since the cell is unloaded + or reused whenever it's flicked out of the viewport. + + \sa layoutChanged() + \section1 Selecting items You can add selection support to TableView by assigning an \l ItemSelectionModel to @@ -1198,6 +1211,22 @@ */ /*! + \qmlsignal QtQuick::TableView::layoutChanged() + \since 6.5 + + This signal is emitted whenever the layout of the + \l {isColumnLoaded()}{loaded} rows and columns has potentially + changed. This will especially be the case when \l forceLayout() + is called, but also when e.g resizing a row or a column, or + when a row or column have entered or left the viewport. + + This signal can be used to for example update the geometry + of overlays. + + \sa forceLayout(), {Overlays and underlays} +*/ + +/*! \qmlattachedproperty TableView QtQuick::TableView::view This attached property holds the view that manages the delegate instance. @@ -3098,6 +3127,8 @@ void QQuickTableViewPrivate::processLoadRequest() if (editIndex.isValid()) updateEditItem(); + + emit q->layoutChanged(); } loadRequest.markAsDone(); @@ -3204,6 +3235,8 @@ void QQuickTableViewPrivate::processRebuildTable() updateEditItem(); updateCurrentRowAndColumn(); + emit q->layoutChanged(); + qCDebug(lcTableViewDelegateLifecycle()) << "current table:" << tableLayoutToString(); qCDebug(lcTableViewDelegateLifecycle()) << "rebuild completed!"; qCDebug(lcTableViewDelegateLifecycle()) << "################################################"; @@ -3556,6 +3589,9 @@ void QQuickTableViewPrivate::unloadEdge(Qt::Edge edge) break; } } + if (rebuildState == RebuildState::Done) + emit q->layoutChanged(); + qCDebug(lcTableViewDelegateLifecycle) << tableLayoutToString(); } diff --git a/src/quick/items/qquicktableview_p.h b/src/quick/items/qquicktableview_p.h index 0366c9d250..bce6b55b54 100644 --- a/src/quick/items/qquicktableview_p.h +++ b/src/quick/items/qquicktableview_p.h @@ -242,6 +242,7 @@ Q_SIGNALS: Q_REVISION(6, 5) void resizableColumnsChanged(); Q_REVISION(6, 5) void resizableRowsChanged(); Q_REVISION(6, 5) void editTriggersChanged(); + Q_REVISION(6, 5) void layoutChanged(); protected: void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp index 12c50185ea..408c3c7603 100644 --- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp +++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp @@ -104,6 +104,7 @@ private slots: void checkForceLayoutEndUpDoingALayout(); void checkForceLayoutDuringModelChange(); void checkForceLayoutWhenAllItemsAreHidden(); + void checkLayoutChangedSignal(); void checkContentWidthAndHeight(); void checkContentWidthAndHeightForSmallTables(); void checkPageFlicking(); @@ -809,6 +810,52 @@ void tst_QQuickTableView::checkForceLayoutWhenAllItemsAreHidden() QCOMPARE(tableViewPrivate->loadedItems.size(), rows * columns); } +void tst_QQuickTableView::checkLayoutChangedSignal() +{ + // Check that the layoutChanged signal is emitted + // when the layout has changed. + LOAD_TABLEVIEW("plaintableview.qml"); + + const QSignalSpy layoutChanges(tableView, &QQuickTableView::layoutChanged); + TestModel model(100, 100); + tableView->setModel(QVariant::fromValue(&model)); + + WAIT_UNTIL_POLISHED; + + QCOMPARE(layoutChanges.size(), 1); + + tableView->forceLayout(); + QCOMPARE(layoutChanges.size(), 2); + + tableView->setRowHeight(1, 10); + WAIT_UNTIL_POLISHED; + QCOMPARE(layoutChanges.size(), 3); + + tableView->setColumnWidth(1, 10); + WAIT_UNTIL_POLISHED; + QCOMPARE(layoutChanges.size(), 4); + + tableView->setContentX(30); + QCOMPARE(layoutChanges.size(), 5); + + tableView->setContentY(30); + QCOMPARE(layoutChanges.size(), 6); + + tableView->setContentX(0); + QCOMPARE(layoutChanges.size(), 7); + + tableView->setContentY(0); + QCOMPARE(layoutChanges.size(), 8); + + model.addRow(1); + WAIT_UNTIL_POLISHED; + QCOMPARE(layoutChanges.size(), 9); + + model.removeRow(1); + WAIT_UNTIL_POLISHED; + QCOMPARE(layoutChanges.size(), 10); +} + void tst_QQuickTableView::checkContentWidthAndHeight() { // Check that contentWidth/Height reports the correct size of the |
