Reputation: 5760
I'm pretty new to working with QML, we have some buttons that are enabled and disabled according to other content on the page. When the other controls are updated there is some JavaScript functions that can be used to determine if the buttons should be enabled or disabled. Originally these functions were assigned to the qml buttons enabled properties, however it seems this isn't enough and a fiddle to make it work is to have a property defined in QML (integer) which is incremented and this is then used by the enabled property to flag an update, this works but seems very hacky and not the correct way to do it.
Item {
id: root
property int qmlChangeFiddle: 0
...
Button {
id: prevImageButton
anchors.left: parent.left
anchors.leftMargin: 24
anchors.top: capturedAreaRect.top
enabled: (root.qmlChangeFiddle > 0)
height: cameraButtonBar.height
width: cameraButtonBar.width * 0.125
icon: "leftarrow.svg"
visible: capturedFrame.visible && (imageCaptureModel.capturableSelected.length > 1)
....
}
}
Incrementing "root.qmllChangeFiddle" will cause it to change and the button enabled, before I was calling a JavaScript routine which returns true or false but this didn't work.
Original qml which doesn't work:
Item {
id: root
...
Button {
id: prevImageButton
anchors.left: parent.left
anchors.leftMargin: 24
anchors.top: capturedAreaRect.top
enabled: images.moreThanOne()
height: cameraButtonBar.height
width: cameraButtonBar.width * 0.125
icon: "leftarrow.svg"
visible: capturedFrame.visible && (imageCaptureModel.capturableSelected.length > 1)
....
}
}
Upvotes: 0
Views: 99
Reputation: 2795
Function return values are not automatically re-evaluated in QML until at least one of the function arguments is updated AND the argument should be a QML object property. I can recommend two approaches:
prevImageButton
to moreThanOne
function while the moreThanOne
accepts a property of its own object (here image) where that property is being changed when the images object is updated Images{
id:images
....
property var updateCounter : 0
function whichEverFunctionThatUpdatesImages(){
...
updateCounter++;
}
function moreThanOne(uc){
// you may want to use it or not
.... return count>0;
}
}
Button{
enabled : images.moreThanOne(images.updateCounter)
}
Images
which is update by moreThanOne
and bind it insteadImages{
id:images
....
property var updateCounter : 0
property var twoOrMore : false
function whichEverFunctionThatUpdatesImages(){
...
twoOrMore = iCount > 1 ;
}
}
Button{
enabled : images.twoOrMore
}
I choose the latter option.
EDIT:
The following example works quite well on btn2 without using the above methods. But if I use anything other than QML properties like an attribute from a javascript object like what is happening on moreThanOne2() method, then it stops to work out of the box and those two approaches for re-evaluation will work.
Item {
id : item
anchors.fill: parent
property var aCounter: 0
property var someObject: ({ counter: 0})
Button{
anchors.top: parent.top
text: 'btn1'
onClicked: {
parent.aCounter++
parent.someObject.counter++
}
}
Button{
anchors.bottom: parent.bottom
anchors.left: parent.left
text: 'btn2'
enabled: item.moreThanOne1()
}
Button{
anchors.bottom: parent.bottom
anchors.right: parent.right
text: 'btn3'
enabled: item.moreThanOne2()
}
function moreThanOne1(){
return aCounter > 1;
}
function moreThanOne2(){
return someObject.counter > 1;
}
}
Upvotes: 2
Reputation: 5760
The actual solution which works is to use Qt.binding:
Item {
id: root
...
Button {
id: prevImageButton
anchors.left: parent.left
anchors.leftMargin: 24
anchors.top: capturedAreaRect.top
enabled: Qt.binding(images.moreThanOne())
height: cameraButtonBar.height
width: cameraButtonBar.width * 0.125
icon: "leftarrow.svg"
visible: capturedFrame.visible && (imageCaptureModel.capturableSelected.length > 1)
....
}
}
Upvotes: 0