Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
5.7.1, 5.8.0
Description
In the attached (simplified) application, the goal is to take a screenshot of each individual DelegateContainer instance. In DelegateContainer.qml, qualifying the call to grabToImage() with the id of the root item container works, but an unqualified call does not. I would expect that an unqualified call in that context should result in the root item's function being called, but it doesn't.
With the following patch:
diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp index c3f8d4f..703de19 100644 --- a/src/quick/items/qquickitemgrabresult.cpp +++ b/src/quick/items/qquickitemgrabresult.cpp @@ -376,6 +376,7 @@ QSharedPointer<QQuickItemGrabResult> QQuickItem::grabToImage(const QSize &target */ bool QQuickItem::grabToImage(const QJSValue &callback, const QSize &targetSize) { + qDebug() << this; QQmlEngine *engine = qmlEngine(this); if (!engine) { qmlWarning(this) << "grabToImage: item has no QML engine";
I get this output when running the application with the incorrect behaviour:
QML debugging is enabled. Only use this in a safe environment. QQuickRow_QML_2(0x19ad7b0, parent=0x1c85aa0, geometry=0,0 190x40) QQuickRow_QML_2(0x19ad7b0, parent=0x1c85aa0, geometry=0,0 190x40) QQuickRow_QML_2(0x19ad7b0, parent=0x1c85aa0, geometry=0,0 190x40) QQuickRow_QML_2(0x19ad7b0, parent=0x1c85aa0, geometry=0,0 190x40) qml: OK: test1.png qml: OK: test2.png qml: OK: test3.png qml: OK: test4.png
And this output with the correct behaviour:
DelegateContainer_QMLTYPE_0(0x1b7e770, parent=0x1a4fe80, geometry=0,0 40x40) DelegateContainer_QMLTYPE_0(0x1b80d40, parent=0x1a4fe80, geometry=50,0 40x40) DelegateContainer_QMLTYPE_0(0x1b82780, parent=0x1a4fe80, geometry=100,0 40x40) DelegateContainer_QMLTYPE_0(0x1b840e0, parent=0x1a4fe80, geometry=150,0 40x40) qml: OK: test1.png qml: OK: test2.png qml: OK: test3.png qml: OK: test4.png
The relevant files from the project for convenience:
main.qml
import QtQuick 2.7 import QtQuick.Layouts 1.3 import QtQuick.Window 2.3 import QtQuick.Controls 2.0 ApplicationWindow { id: window width: 800 height: 640 visible: true title: "repeater-loader-grabToImage" Component.onCompleted: { x = Screen.width / 2 - width / 2 y = Screen.height / 2 - height / 2 takeScreenshots() } Shortcut { sequence: "Ctrl+Q" onActivated: Qt.quit() } function takeScreenshots() { var repeater = stateRepeater.itemAt(0).nestedRepeater for (var j = 0; j < repeater.count; ++j) { repeater.itemAt(j).takeScreenshot() } } Repeater { id: stateRepeater model: 1 Row { id: dprRow spacing: 10 property alias nestedRepeater: dprRepeater Repeater { id: dprRepeater model: 4 DelegateContainer { id: delegateContainer } } } } }
DelegateContainer.qml
import QtQuick 2.0 Item { id: container x: index * (width + 10) width: delegate.width height: delegate.height property int dpr: index + 1 function takeScreenshot() { // Incorrect - takes screenshot of all items grabToImage(function(result) { // Correct - only takes screenshot of container // container.grabToImage(function(result) { var fileName = "test" + dpr + ".png" var res = result.saveToFile(fileName) console.log(res ? "OK:" : "### NOK:", fileName) }) } Loader { id: delegate sourceComponent: Rectangle { width: 40 height: 40 color: "blue" } } }