diff options
author | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2018-09-14 10:03:27 +0200 |
---|---|---|
committer | Richard Moe Gustavsen <richard.gustavsen@qt.io> | 2018-09-17 07:51:20 +0000 |
commit | f4e96bf319b14bc64d9c92551303991b4f303846 (patch) | |
tree | 8c893a6a22b97519ded0d62d1ab64cdc1d572bf6 /tests/auto/quick/qquicktableview/tst_qquicktableview.cpp | |
parent | 1dac47c1418b44cf4a56b42bfca2b277795fd213 (diff) |
QQuickTableView: build the table when the component is finalized
componentComplete() is called on us after all static values
have been assigned, but before bindings to any ancestors
have been evaluated. Especially this means that if our size
is bound to the parents size, it will not be ready at that point.
Since we cannot build the table without knowing our own size, we
waited for the updatePolish() call before we started to build
the table.
The problem with that strategy, is that any asynchronous loaders that
TableView might be inside would already be finished by the time
we received the updatePolish() call. The result would be that we
ended up loading all the delegate items synchronously instead of
asynchronously. (As soon as a loader has finished loading the initial
item, async loading will no longer be used).
This patch will therefore add a componentFinalized function that gets
called after all bindings have been evaluated, but before the loader
has finished. When receiving this call, we load the delegate items (and
build the table).
A nice side effect is that the table will also be ready
by the time Component.onCompeted is emitted to the QML
app. This means that e.g contentWidth/Height has valid values.
Change-Id: Ief92d2fecfaea54f6191da116ed4ba79cc673b01
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'tests/auto/quick/qquicktableview/tst_qquicktableview.cpp')
-rw-r--r-- | tests/auto/quick/qquicktableview/tst_qquicktableview.cpp | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp index a1951bdf90..039fb91da0 100644 --- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp +++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp @@ -31,6 +31,7 @@ #include <QtQuick/qquickview.h> #include <QtQuick/private/qquicktableview_p.h> #include <QtQuick/private/qquicktableview_p_p.h> +#include <QtQuick/private/qquickloader_p.h> #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcontext.h> @@ -55,15 +56,28 @@ static const char *kModelDataBindingProp = "modelDataBinding"; Q_DECLARE_METATYPE(QMarginsF); -#define LOAD_TABLEVIEW(fileName) \ - view->setSource(testFileUrl(fileName)); \ - view->show(); \ - QVERIFY(QTest::qWaitForWindowActive(view)); \ +#define DECLARE_TABLEVIEW_VARIABLES \ auto tableView = view->rootObject()->property(kTableViewPropName).value<QQuickTableView *>(); \ QVERIFY(tableView); \ auto tableViewPrivate = QQuickTableViewPrivate::get(tableView); \ Q_UNUSED(tableViewPrivate) +#define LOAD_TABLEVIEW(fileName) \ + view->setSource(testFileUrl(fileName)); \ + view->show(); \ + QVERIFY(QTest::qWaitForWindowActive(view)); \ + DECLARE_TABLEVIEW_VARIABLES + +#define LOAD_TABLEVIEW_ASYNC(fileName) \ + view->setSource(testFileUrl("asyncloader.qml")); \ + view->show(); \ + QVERIFY(QTest::qWaitForWindowActive(view)); \ + auto loader = view->rootObject()->property("loader").value<QQuickLoader *>(); \ + loader->setSource(QUrl::fromLocalFile("data/" fileName)); \ + QTRY_VERIFY(loader->item()); \ + QCOMPARE(loader->status(), QQuickLoader::Status::Ready); \ + DECLARE_TABLEVIEW_VARIABLES + #define WAIT_UNTIL_POLISHED \ QVERIFY(tableViewPrivate->polishScheduled); \ QTRY_VERIFY(!tableViewPrivate->polishScheduled) @@ -139,6 +153,7 @@ private slots: void checkChangingModelFromDelegate(); void checkRebuildViewportOnly(); void useDelegateChooserWithoutDefault(); + void checkTableviewInsideAsyncLoader(); }; tst_QQuickTableView::tst_QQuickTableView() @@ -1815,6 +1830,46 @@ void tst_QQuickTableView::useDelegateChooserWithoutDefault() WAIT_UNTIL_POLISHED; }; +void tst_QQuickTableView::checkTableviewInsideAsyncLoader() +{ + // Check that you can put a TableView inside an async Loader, and + // that the delegate items are created before the loader is ready. + LOAD_TABLEVIEW_ASYNC("asyncplain.qml"); + + // At this point the Loader has finished + QCOMPARE(loader->status(), QQuickLoader::Ready); + + // Check that TableView has finished building + QCOMPARE(tableViewPrivate->rebuildScheduled, false); + QCOMPARE(tableViewPrivate->rebuildState, QQuickTableViewPrivate::RebuildState::Done); + + // Check that all expected delegate items have been loaded + const qreal delegateWidth = 100; + const qreal delegateHeight = 50; + int expectedColumns = qCeil(tableView->width() / delegateWidth); + int expectedRows = qCeil(tableView->height() / delegateHeight); + QCOMPARE(tableViewPrivate->loadedTable.width(), expectedColumns); + QCOMPARE(tableViewPrivate->loadedTable.height(), expectedRows); + + // Check that the loader was still in a loading state while TableView was creating + // delegate items. If we delayed creating delegate items until we got the first + // updatePolish() callback in QQuickTableView, this would not be the case. + auto statusWhenDelegate0_0Completed = qvariant_cast<QQuickLoader::Status>( + loader->item()->property("statusWhenDelegate0_0Created")); + auto statusWhenDelegate5_5Completed = qvariant_cast<QQuickLoader::Status>( + loader->item()->property("statusWhenDelegate5_5Created")); + QCOMPARE(statusWhenDelegate0_0Completed, QQuickLoader::Loading); + QCOMPARE(statusWhenDelegate5_5Completed, QQuickLoader::Loading); + + // Check that TableView had a valid geometry when we started to build. If the build + // was started too early (e.g upon QQuickTableView::componentComplete), width and + // height would still be 0 since the bindings would not have been evaluated yet. + qreal width = loader->item()->property("tableViewWidthWhileBuilding").toReal(); + qreal height = loader->item()->property("tableViewHeightWhileBuilding").toReal(); + QVERIFY(width > 0); + QVERIFY(height > 0); +}; + QTEST_MAIN(tst_QQuickTableView) #include "tst_qquicktableview.moc" |