QQuickTableView: don't load any delegates if viewport has zero size

When TableView has a zero size, the viewport will have zero
size as well, and there is no reason to load any delegates.

This patch will ensure that we return early from
loadInitialTable() when we detect that this is the case.

This will also stop a warning from being printed when
the delegate has it's implicitWidth bound to
tableView.width, and tableView.width == 0.

Pick-to: 6.5
Change-Id: I659eb098f7c5c25c8359876f7664499381f94b98
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
This commit is contained in:
Richard Moe Gustavsen 2022-12-22 13:55:09 +01:00
parent c5317b4b59
commit ebefb583c8
4 changed files with 84 additions and 2 deletions

View File

@ -2964,6 +2964,12 @@ void QQuickTableViewPrivate::relayoutTableItems()
{
qCDebug(lcTableViewDelegateLifecycle);
if (viewportRect.isEmpty()) {
// This can happen if TableView was resized down to have a zero size
qCDebug(lcTableViewDelegateLifecycle()) << "Skipping relayout, viewport has zero size";
return;
}
qreal nextColumnX = loadedTableOuterRect.x();
qreal nextRowY = loadedTableOuterRect.y();
@ -3493,6 +3499,11 @@ void QQuickTableViewPrivate::loadInitialTable()
return;
}
if (viewportRect.isEmpty()) {
qCDebug(lcTableViewDelegateLifecycle()) << "viewport has zero size, leaving table empty";
return;
}
// Load top-left item. After loaded, loadItemsInsideRect() will take
// care of filling out the rest of the table.
loadRequest.begin(topLeft, topLeftPos, QQmlIncubator::AsynchronousIfNested);

View File

@ -8,6 +8,8 @@ Item {
objectName: "outer"
TableView {
id: tableView
width: 10
height: 10
model: 1
property string foo: "foo"
delegate: Text {
@ -19,6 +21,8 @@ Item {
TableView {
id: tableView2
width: 10
height: 10
model: 1
delegate: Text {
required property int index

View File

@ -0,0 +1,29 @@
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
import QtQuick
import QtQuick.Window
Item {
width: 640
height: 450
property alias tableView: tableView
TableView {
id: tableView
width: 0
height: 0
delegate: tableViewDelegate
}
Component {
id: tableViewDelegate
Rectangle {
objectName: "tableViewDelegate"
implicitWidth: tableView.width
implicitHeight: 50
}
}
}

View File

@ -86,6 +86,7 @@ private slots:
void checkPreload();
void checkZeroSizedDelegate();
void checkImplicitSizeDelegate();
void checkZeroSizedTableView();
void checkColumnWidthWithoutProvider();
void checkColumnWidthAndRowHeightFunctions();
void checkDelegateWithAnchors();
@ -419,6 +420,43 @@ void tst_QQuickTableView::checkImplicitSizeDelegate()
}
}
void tst_QQuickTableView::checkZeroSizedTableView()
{
// Check that we don't load any delegates if TableView
// itself has zero size.
LOAD_TABLEVIEW("zerosizedtableview.qml");
auto model = TestModelAsVariant(100, 100);
tableView->setModel(model);
WAIT_UNTIL_POLISHED;
QVERIFY(tableViewPrivate->loadedItems.isEmpty());
// Resize TableView. This should load delegate. Since
// the delegate's implicitWidth is bound to TableView.width,
// we expect the delegates to now get the same width.
tableView->setWidth(200);
tableView->setHeight(100);
WAIT_UNTIL_POLISHED;
QCOMPARE(tableViewPrivate->loadedItems.size(), 2);
const auto item = tableView->itemAtCell(0, 0);
QVERIFY(item);
QCOMPARE(item->width(), 200);
// Hide TableView again, and check that all items are
// unloaded, except the topLeft corner item.
tableView->setWidth(0);
tableView->setHeight(0);
WAIT_UNTIL_POLISHED;
QCOMPARE(tableViewPrivate->loadedItems.size(), 1);
}
void tst_QQuickTableView::checkColumnWidthWithoutProvider()
{
// Checks that a function isn't assigned to the columnWidthProvider property
@ -5703,7 +5741,7 @@ void tst_QQuickTableView::boundDelegateComponent()
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
QTest::ignoreMessage(
QtWarningMsg, qPrintable(QLatin1String("%1:14: ReferenceError: index is not defined")
QtWarningMsg, qPrintable(QLatin1String("%1:16: ReferenceError: index is not defined")
.arg(url.toString())));
QScopedPointer<QObject> o(c.create());
@ -5734,7 +5772,7 @@ void tst_QQuickTableView::boundDelegateComponent()
for (int i = 0; i < 3 * 2; ++i) {
QTest::ignoreMessage(
QtWarningMsg,
qPrintable(QLatin1String("%1:50:21: ReferenceError: model is not defined")
qPrintable(QLatin1String("%1:54:21: ReferenceError: model is not defined")
.arg(url.toString())));
}