Wolf
Wolf

Reputation: 119

QML button toggling

I want to have a button in QML that has 3 states: off, pressed, and on. right now I have the following for code, but it does not work. right now i have a toggle function that sets the new state based on the previous state, but if the previous state is "pressed" then how can I detect the state before it is pressed to toggle the button?

the following is not the whole class, just the relevant function and Mouse Area

    Rectangle {
        id: button1
        function toggle(){
            var tempstate = button1.state
            if (tempstate=="on") {tempstate = "off"; } else { tempstate ="on"}
        }

        MouseArea {
            anchors.fill: parent
            onPressed: parent.state = "pressed"
            onReleased: parent.toggle()
        }

Upvotes: 1

Views: 5793

Answers (3)

Krzysztof Piekutowski
Krzysztof Piekutowski

Reputation: 674

Have you considered using Button? It can be checked so it's like on/off state and it has property 'pressed' indicating if button is currently pressed.

import QtQuick.Controls 1.3
Button {
    checkable: true
    text: pressed ? "pressed" : (checked ? "on" : "off")
}

Upvotes: 2

Wolf
Wolf

Reputation: 119

I've solved this using ternary conditional statements. instead of using 3 states, I use 2 states, where each state has a conditional based on the MouseArea.pressed property.

If this is somehow hackish or improper for QML, please correct me with a more idiomatic solution.

the color property of the Rectangle can be replaced with the source in an image item, or other properties to create other "3 state" clickable items.

Here is the link to QML's documentation where i realized this could be done.

Example code:

Rectangle {
    id: button1
    state: "off"
    color: "red"
    MouseArea {
        id: button1area
        anchors.fill: parent
        onReleased: parent.state == "on" ? parent.state = "off" : parent.state = "on"
    }
    states: [
        State {
            name: "off"
            PropertyChanges { target: button1; color: button1area.pressed ? "red" : "blue" }
        },
        State {
            name: "on"
            PropertyChanges { target: button1; color: button1area.pressed ? "green" : "blue" }
        }
    ]
}

Upvotes: 1

AmanVirdi
AmanVirdi

Reputation: 1685

Try to use this:

Rectangle {
   id: button1

   function toggle(){
       var tempstate = button1.state;  //write var if is local variable
       if (tempstate=="on") {state = "off"; } else { state = "on"}
   }

   MouseArea {
   anchors.fill: parent
   onPressed: parent.state = "pressed"
   onReleased: parent.toggle()
}

"tempstate" is holding the name of the state which is string. Its not having object reference. You can directly access the state property in the function.

Upvotes: 0

Related Questions