diff options
author | Volker Hilsheimer <[email protected]> | 2022-11-18 14:20:20 +0100 |
---|---|---|
committer | Volker Hilsheimer <[email protected]> | 2022-12-01 06:26:40 +0100 |
commit | d1b9a4cacfb966cf0a37983d8f8044f3aedf5de3 (patch) | |
tree | 0124b6f8433f8e3ef9cde5d151ac34af778e4e8b | |
parent | 8b100bed5237b1ec864f059d7fb04b94fd874f49 (diff) |
QQuickItem: Fix effective visibility for items without parent
Items are visible if they are children of a visible parent, and not
explicitly hidden. The effectiveVisible member stores the state and is
updated when conditions that impact the item visibility changes.
The old code returned true for items outside a visual hierarchy, which
broke signal emission when items were removed from a parent, e.g.
because the parent got destroyed. With this change, items removed from
a visual hierarchy will emit the visibleChanged signal.
Note: QQuickItem initializes the effectiveVisible member to true, even
if the item was created without parent item. Visual items are required
to be added to a visual hierarchy via setParentItem. For this reason,
newly created items never emit visibleChanged when they are added to
a parent.
Adjust the QQuickItem::visible test - it creates an item hierarchy
without window. Such items are never visible, so add a window and
parent the test item hierarchy to the window's content item.
This fixes the expected failures in the tests. It does introduce an
incompatibility with QGraphicsView and QGraphicsItem, which continue
to return true from QGraphicsItem::isVisible for items that are not
in an item hierarchy.
[ChangeLog][Qt Quick][QQuickItem] The visible property of Items without
a parent now always returns false, and the visibleChanged signal gets
emitted when the parent item of a visible item becomes null.
Fixes: QTBUG-108213
Change-Id: If4b2947cefd1407853f0f29e6c3fdbd49fc9af65
Reviewed-by: Fabian Kosmale <[email protected]>
Reviewed-by: Shawn Rutledge <[email protected]>
-rw-r--r-- | src/quick/items/qquickitem.cpp | 6 | ||||
-rw-r--r-- | tests/auto/quick/qquickitem/tst_qquickitem.cpp | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquickitem2/tst_qquickitem.cpp | 20 |
3 files changed, 5 insertions, 23 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index a254efb8fc..5f86139566 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -6410,10 +6410,8 @@ void QQuickItem::setEnabled(bool e) bool QQuickItemPrivate::calcEffectiveVisible() const { - // XXX todo - Should the effective visible of an element with no parent just be the current - // effective visible? This would prevent pointless re-processing in the case of an element - // moving to/from a no-parent situation, but it is different from what graphics view does. - return explicitVisible && (!parentItem || QQuickItemPrivate::get(parentItem)->effectiveVisible); + // An item is visible if it is a child of a visible parent, and not explicitly hidden. + return explicitVisible && parentItem && QQuickItemPrivate::get(parentItem)->effectiveVisible; } bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible) diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index e00c4cf42d..23616156d6 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -1094,7 +1094,9 @@ void tst_qquickitem::setParentItem() void tst_qquickitem::visible() { + QQuickWindow window; QQuickItem *root = new QQuickItem; + root->setParentItem(window.contentItem()); QQuickItem *child1 = new QQuickItem; child1->setParentItem(root); diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp index 972755a5f5..f7601cade1 100644 --- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp @@ -4036,7 +4036,7 @@ void tst_QQuickItem::signalsOnDestruction() // Visual children, but not QObject children. // Note: QQuickItem's visible property defaults to true after creation, as visual // items are always expected to be added to a visual hierarchy. So for the sake - // of this test we first add, and then remove the item from a parent. This explicily + // of this test we first add, and then remove the item from a parent. This explicitly // sets the effective visibility to false. std::unique_ptr<QQuickItem> parent(new QQuickItem(window.contentItem())); QVERIFY(parent->isVisible()); @@ -4044,15 +4044,11 @@ void tst_QQuickItem::signalsOnDestruction() child->setVisible(childVisible); child->setParentItem(parent.get()); child->setParentItem(nullptr); - QEXPECT_FAIL("Both visible", "Item without parent should not be visible", Continue); - QEXPECT_FAIL("Child visible", "Item without parent should not be visible", Continue); QVERIFY(!child->isVisible()); std::unique_ptr<QQuickItem> grandChild(new QQuickItem); grandChild->setVisible(grandChildVisible); grandChild->setParentItem(child.get()); grandChild->setParentItem(nullptr); - QEXPECT_FAIL("Both visible", "Item without parent should not be visible", Continue); - QEXPECT_FAIL("Grand child visible", "Item without parent should not be visible", Continue); QVERIFY(!grandChild->isVisible()); QSignalSpy childrenSpy(parent.get(), &QQuickItem::childrenChanged); @@ -4070,8 +4066,6 @@ void tst_QQuickItem::signalsOnDestruction() ++expectedChildVisibleCount; QCOMPARE(visibleChildrenSpy.count(), expectedChildVisibleCount); QCOMPARE(childParentSpy.count(), 1); - QEXPECT_FAIL("Both visible", "Child added to visible parent should emit", Continue); - QEXPECT_FAIL("Child visible", "Child added to visible parent should emit", Continue); QCOMPARE(childVisibleSpy.count(), expectedChildVisibleCount); QCOMPARE(childChildrenSpy.count(), 0); QCOMPARE(childVisibleChildrenSpy.count(), 0); @@ -4080,16 +4074,12 @@ void tst_QQuickItem::signalsOnDestruction() QCOMPARE(childrenSpy.count(), 1); QCOMPARE(visibleChildrenSpy.count(), expectedChildVisibleCount); QCOMPARE(childParentSpy.count(), 1); - QEXPECT_FAIL("Both visible", "Child added to visible parent should emit", Continue); - QEXPECT_FAIL("Child visible", "Child added to visible parent should emit", Continue); QCOMPARE(childVisibleSpy.count(), expectedChildVisibleCount); QCOMPARE(childChildrenSpy.count(), 1); if (grandChildVisible && childVisible) ++expectedGrandChildVisibleCount; QCOMPARE(childVisibleChildrenSpy.count(), expectedGrandChildVisibleCount); QCOMPARE(grandChildParentSpy.count(), 1); - QEXPECT_FAIL("Both visible", "Visible grand child added to visible child should emit", Continue); - QEXPECT_FAIL("Grand child visible", "Adding visible grand child to hidden child should not emit", Continue); QCOMPARE(grandChildVisibleSpy.count(), expectedGrandChildVisibleCount); parent.reset(); @@ -4102,16 +4092,11 @@ void tst_QQuickItem::signalsOnDestruction() QCOMPARE(childChildrenSpy.count(), 1); if (childVisible) ++expectedChildVisibleCount; - QEXPECT_FAIL("Both visible", "Items without (grand) parent should not be visible on screen", Continue); - QEXPECT_FAIL("Child visible", "Items without (grand) parent should not be visible on screen", Continue); QCOMPARE(childVisibleSpy.count(), expectedChildVisibleCount); if (childVisible && grandChildVisible) ++expectedGrandChildVisibleCount; - QEXPECT_FAIL("Both visible", "Items without (grand) parent should not be visible on screen", Continue); QCOMPARE(childVisibleChildrenSpy.count(), expectedGrandChildVisibleCount); QCOMPARE(grandChildParentSpy.count(), 1); - QEXPECT_FAIL("Both visible", "Items without (grand) parent should not be visible on screen", Continue); - QEXPECT_FAIL("Grand child visible", "Items without (grand) parent should not be visible on screen", Continue); QCOMPARE(grandChildVisibleSpy.count(), expectedGrandChildVisibleCount); } @@ -4142,9 +4127,7 @@ void tst_QQuickItem::visibleChanged() QCOMPARE(parentItemSpy.count(), 0); QCOMPARE(childItemSpy.count(), 0); QVERIFY(!loaderChild->parentItem()); - QEXPECT_FAIL("", "QTBUG-108213", Continue); QCOMPARE(loaderChildSpy.count(), 1); - QEXPECT_FAIL("", "QTBUG-108213", Continue); QCOMPARE(loaderChild->isVisible(), false); delete parentItem.data(); @@ -4153,7 +4136,6 @@ void tst_QQuickItem::visibleChanged() QVERIFY(!childItem->parentItem()); QCOMPARE(parentItemSpy.count(), 0); - QEXPECT_FAIL("", "QTBUG-108213", Continue); QCOMPARE(childItemSpy.count(), 1); } |