QML ReferenceError within Drawer
-
This is a (at least to me) strange one.
I've got a very simple QML file based on an Item, which is loaded into the GUI via a higher-level Loader. The Item has a number of child elements, and makes use of a Repeater to populate buttons (MultiTouchPointAreas). I also have a Drawer, whose properties are set depending on the button pressed within the Item, through the use of a global property variable.
Item { id: mainItem property var mainArr: ["", ""] Item { id: childItem Grid { id: childGrid columns: 2 ColumnLayout { width: 100 spacing: 10 Repeater { id: mainRepeater model: ["1", "2", "3"] ...Other mainRepeater elements skipped MultiTouchPointArea { anchors.fill: parent onReleased: { mainArr = [index, "New String"] mainDrawer.open() } } } } } } Drawer { id: mainDrawer ..Other mainDrawer properties and elements skipped MultiTouchPointArea { anchors.fill: parent //The MultiTouchPointArea is within a Grid and ColumnLayout, similar to above onReleased: { if (mainArr[1] === "New String") { console.log("New String") //Update the mainArr property array; this is where the ReferenceError occurs mainArr = [0, "Next String"] } else if (mainArr[1] === "Next String") { console.log("Next String") } } } } }
As shown above, when a MultiPointTouchArea is clicked, its index and a string are written to the global mainArr variable. This information is then used in the Drawer; the above is a simplification of this, which highlights the issue I'm facing. As shown above, I would expect the Drawer MultiPointTouchArea to print "New String" and then "Next String" when clicked the first and second time. However, on first clicking the Drawer MultiPointTouchArea, I get the "New String" console log as expected, with the following ReferenceError:
ReferenceError: mainArr is not defined
However, if I then clicked the MultiPointTouchArea a second time, I again get the "New String" console log, this time without the ReferenceError. If I then click the MultiPointTouchArea a third time, I get "Next String" printed in the console log. Note that this behaviour is exactly the same if I explicitly use the mainItem ID (i.e. mainItem.mainArr = [0, "Next String"]).
What's going on here? It seems like the mainArr variable isn't initialised within the scope of the Drawer, despite it correctly being able to read the mainArr variable in the onReleased if statement? Somehow the ReferenceError is resolved when the MultiPointTouchArea onReleased code is run for the second time? Also note that updating the mainArr variable from within the child elements of mainItem works without issue; I'm only experiencing this issue from within the Drawer. I've specifically made the Drawer a child of mainItem so that the global properties are available to it.
-
I just tried a slightly different approach; I've established a function (within the mainItem Item) which updates the mainArr array as such:
Item { id: mainItem property var mainArr: ["", ""] function updateMainArr(string1, string2) { mainArr = [string1, string2] } Item { id: childItem ...etc
Instead of updating mainArr directly from within the Drawer MultiTouchPointArea (as above), I instead call this function. However the results are essentially the same as before. On first press, I get the following ReferenceError:
ReferenceError: updateMainArr is not defined
On second press the "New String" text is printed to the console, and on third press the "Next String" text is printed to the console. Again, it appears that when the Drawer is open()ed, it is not within the scope of its parent (mainItem), which is then resolved after the first press of the Drawer's MultiTouchPointArea?
-
I've just found another, possibly more telling/strange oddity. I've been thinking that there's a disconnect between the Drawer and the parent mainItem Item, but it seems that the Drawer itself might have an issue. I created a property variable within the Drawer, and try to update its value when the MultiTouchPointArea is pressed instead of the mainItem mainArr:
Drawer { id: mainDrawer property var testVar: "" ..Other mainDrawer properties and elements skipped MultiTouchPointArea { anchors.fill: parent //The MultiTouchPointArea is within a Grid and ColumnLayout, similar to above onReleased: { if (mainArr[1] === "New String") { console.log("New String") //Instead of updating the mainItem mainArr variable, let's update the Drawer's own testVar mainDrawer.testVar = "Some String" } else if (mainArr[1] === "Next String") { console.log("Next String") } } } }
With the above amended approach, I get the same ReferenceError:
ReferenceError: mainDrawer is not defined
How is it that the id of the Drawer itself is not defined? Again, this issue is resolved on the second press event. Note that if I don't use the mainDrawer id in addressing the variable (i.e. testVar = "Some String" instead of mainDrawer.testVar = "Some String") I get the following error instead (which is not resolved on the second press event):
Error: Invalid write to global property value "testVar"
-
I've decided to move all properties to c++ and not use properties within QML itself. As such, this issue isn't relevant anymore, but I'd still be interested to understand what's going on here. I suspect it's due to the Drawer's parent being the Overlay, rather than the mainItem itself.