Reputation: 8242
I'm trying to nail down the specifics of function scope in QML. The examples in the documentation appear to often be incorrect (or incomplete). I'll take a pretty typical example right from the JavaScript Host Environment doc page. I'm using Qt 5.3.
Item {
width: 200; height: 100
function mouseAreaClicked(area) {
console.log("Clicked in area at: " + area.x + ", " + area.y);
}
// This will not work because this is undefined
MouseArea {
height: 50; width: 200
onClicked: mouseAreaClicked(this)
}
// This will pass area2 to the function
MouseArea {
id: area2
y: 50; height: 50; width: 200
onClicked: mouseAreaClicked(area2)
}
}
If I take this and paste it into a new empty project right inside the root ApplicationWindow object it doesn't work. I've seen many examples like this and they all behave the same. The call to the function mouseAreaClicked() generates a Reference Error. I can either move the function up so that it's directly inside the root object, or I can assign an id and call the function through the id.
Is this how this is supposed to work? Are functions only available if they are part of the root object? Is this something that changed recently? Is it releated to the ApplicationWindow object? I can't find any mention of this in the documentation. Also this example is somewhat interesting because the topic under discussion: the this pointer, doesn't behave as described. The code invoked by the first MouseArea works just as well as the code invoked by the 2nd MouseArea so I'm also not sure what to make of that.
Any insight appreciated.
Upvotes: 3
Views: 1359
Reputation: 60034
I think that the point it's the definition of 'processing unit'. Probably (I will check this later) when you paste some code intended to reside in a file.qml - then intended to (re)define a somewhat autonomous component - you change the nesting scope, and - I deduce from the sample you report, and my experience - only root' properties are visible unqualified in deeply nested levels. I've tested so far that the obvious 'explicit qualification'
...
MouseArea {
id: area2
y: 50; height: 50; width: 200
onClicked: parent.mouseAreaClicked(area2)
}
...
works as expected. Maybe they should take your question into account, and correct the sample code, or explain why you shouldn't copy/pastethat snippet. Overall, I find your question reasonable.
FWIW, I have code that - inside derived QML components - calls utilities that I placed in the root of my application. Here is my utility
-- main file
ApplicationWindow {
...
// utility to assign multiple members by name
function assign(target, source) {
for (var k in source)
target[k] = source[k]
}
...
}
-- component file(s)
MouseArea {
...
anchors.fill: parent
drag.target: dr
onClicked: {
//console.log("onClicked")
var i = {x:mouse.x, y:mouse.y, visible:true, width:10, height:10}
assign(dr, i)
assign(area, i)
}
...
}
Upvotes: 1