QQuickComboBox: fix popup's deferred execution

Unlike other delegates, such as background and contentItem, popup is
not unconditionally executed upon component completion. For performance
reasons, its execution is delayed until the popup is needed, that is,
the popup is accessed or shown.

When the popup is accessed, we use the current completion status via
isComponentComplete() to determine whether its execution must be
completed immediately, or if we can wait until componentComplete().
However, if the popup was accessed while the combobox itself was being
completed (used in ComboBox's bindings), the popup was never completed
because isComponentComplete() was still returning false even though the
popup was actually being indirectly accessed from componentComplete().
A simple execution order change, to complete the combobox itself before
the popup, fixes the problem.

Task-number: QTBUG-65962
Change-Id: I4764eb7e273e7f6fa1dab1a65a02b87722ee7cba
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
This commit is contained in:
J-P Nurmi 2018-01-24 13:44:00 +01:00
parent aca950e43a
commit c3858bd539
2 changed files with 15 additions and 1 deletions

View File

@ -1603,9 +1603,9 @@ void QQuickComboBox::componentComplete()
{
Q_D(QQuickComboBox);
d->executeIndicator(true);
QQuickControl::componentComplete();
if (d->popup)
d->executePopup(true);
QQuickControl::componentComplete();
if (d->delegateModel && d->ownModel)
static_cast<QQmlDelegateModel *>(d->delegateModel)->componentComplete();

View File

@ -481,6 +481,20 @@ void tst_customization::comboPopup()
QTest::mouseClick(&window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1));
QVERIFY(qt_createdQObjects()->contains("combobox-popup-simple"));
}
reset();
{
// test that ComboBox::popup is completed upon component completion (if appropriate)
QQmlComponent component(engine);
component.setData("import QtQuick 2.9; import QtQuick.Controls 2.2; ComboBox { id: control; contentItem: Item { visible: !control.popup.visible } popup: Popup { property bool wasCompleted: false; Component.onCompleted: wasCompleted = true } }", QUrl());
QScopedPointer<QQuickItem> comboBox(qobject_cast<QQuickItem *>(component.create()));
QVERIFY(comboBox);
QObject *popup = comboBox->property("popup").value<QObject *>();
QVERIFY(popup);
QCOMPARE(popup->property("wasCompleted"), QVariant(true));
}
}
QTEST_MAIN(tst_customization)