How to make a QML toggle button that tracks/controls any boolean property

Jeremy Friesner

My QML/QtQuick exercise for today is to make a little ToggleButton widget that I can instantiate to monitor the state of a specified boolean QML property, and that also toggles that property's state when I click on the ToggleButton.

So far I have this for my ToggleButton component:

// Contents of ToggleButton.qml
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4

Button {
    property bool isActive: false

    onClicked: {
        isActive = !isActive;
    }

    style: ButtonStyle {
        background: Rectangle {
            border.width: control.activeFocus ? 2 : 1
            border.color: "black"
            radius: 4
            color:  isActive ? "red" : "gray";
        }
    }
}

.... and here is my little test harness that I use to see whether it works the way I want it to, or not:

// Contents of main.qml
import QtQuick 2.6
import QtQuick.Window 2.2

Window {
   visible: true
   width: 360
   height: 360

   Rectangle {
      property bool lighten: false;

      id:blueRect
      x: 32; y:32; width:64; height:64
      color: lighten ? "lightBlue" : "blue";

      MouseArea {
         anchors.fill: parent
         onClicked:    parent.lighten = !parent.lighten;
      }
   }

   Rectangle {
      property bool lighten: false;

      id:greenRect
      x:192; y:32; width:64; height:64
      color: lighten ? "lightGreen" : "green";

      MouseArea {
         anchors.fill: parent
         onClicked:    parent.lighten = !parent.lighten;
      }
   }

   ToggleButton {
      x:32; y:128
      text: "Bright Blue Rect"
      isActive: blueRect.lighten
   }

   ToggleButton {
      x:192; y:128
      text: "Bright Green Rect"
      isActive: greenRect.lighten
   }
}

You can run this by saving the code to ToggleButton.qml and main.qml (respectively) and then running "qmlscene main.qml".

Note that if you click on the blue or green rectangles, it works as expected; the boolean "lighten" property of the Rectangle object is toggled on and off, causing the Rectangle to change color, and the associated ToggleButton also reacts appropriately (by turning itself red when the "lighten" property is true, and gray when the "lighten" property is false).

So far, so good, but if you then click on the ToggleButton itself, the binding is broken: that is, clicking on the ToggleButton causes the ToggleButton to turn red/gray as expected, but the rectangle's color doesn't follow suit, and after doing that, clicking on the rectangle no longer causes the ToggleButton's state to change, either.

My question is, what is the trick to doing this properly, so that I always have a bidirectional correspondence between the ToggleButton and the property it is tracking? (Note that the ideal solution would add as little code as possible to main.qml, since I'd like this functionality to be encapsulated inside ToggleButton.qml, to minimize the amount of complexity exposed to the rest of my QML app)

Jeremy Friesner

It looks like one way to solve this problem is to have the ToggleButton declare its state using an alias-property, rather than a regular property. That way there is only the one external property (since the ToggleButton's internal property is really just an alias to the external one), and therefore no bidirectional binding is necessary. Here's an updated version of the QML code that works as expected:

ToggleButton.qml:

// Contents of ToggleButton.qml
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4

Button {
    onClicked: {
        isActive = !isActive;
    }

    style: ButtonStyle {
        background: Rectangle {
            border.width: control.activeFocus ? 2 : 1
            border.color: "black"
            radius: 4
            color:  isActive ? "red" : "gray";
        }
    }    
}  

main.qml:

// Contents of main.qml
import QtQuick 2.6
import QtQuick.Window 2.2

Window {
   visible: true
   width: 360
   height: 360

   Rectangle {
      property bool lighten: false;

      id:blueRect
      x: 32; y:32; width:64; height:64
      color: lighten ? "lightBlue" : "blue";

      MouseArea {
         anchors.fill: parent
         onClicked:    parent.lighten = !parent.lighten;
      }
   }

   Rectangle {
      property bool lighten: false;

      id:greenRect
      x:192; y:32; width:64; height:64
      color: lighten ? "lightGreen" : "green";

      MouseArea {
         anchors.fill: parent
         onClicked:    parent.lighten = !parent.lighten;
      }
   }

   ToggleButton {
      x:32; y:128
      text: "Bright Blue Rect"
      property alias isActive: blueRect.lighten
   }

   ToggleButton {
      x:192; y:128
      text: "Bright Green Rect"
      property alias isActive: greenRect.lighten
   }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

QML: How do you toggle boolean?

From Dev

How to make toggle button transparent

From Dev

How to make the toggle and the button change if any one of it had changes in different HTML

From Dev

How to change the value of a property on toggle button IsChecked?

From Dev

How to make visible property work immediately in QML?

From Dev

How to make image to fill qml controls button

From Dev

How to store multiple Toggle button states in a Boolean Array in Android

From Dev

How to bind paper-toggle-button to a Boolean in Polymer

From Dev

In awk, how can I make a boolean value that I can toggle it?

From Dev

Radio button for boolean property

From Dev

make a Toggle button in javascript

From Java

How to toggle a boolean?

From Dev

Button toggle div visible property

From Dev

How to toggle a Boolean on checkbox in Angularjs

From Dev

Using FXML and JavaFX, how do I set a boolean variable using toggle button?

From Dev

How to toggle button with value

From Dev

how to use toggle in button

From Dev

How to toggle keybindings with a button

From Dev

Make Image Button Behave Like a Toggle Button

From Dev

Java/Android - How can I make a toggle button change state by pressing another button?

From Dev

toggle divs left property on button click

From Dev

QML: Make property readonly in derived class

From Java

Does any language have a unary boolean toggle operator?

From Java

How to toggle boolean state of react component?

From Dev

How to toggle a boolean in postgres in one query

From Dev

How do I toggle a boolean array in Python?

From Dev

How to toggle boolean value on click with knockout?

From Dev

How to toggle a boolean in postgres in one query

From Dev

How to toggle boolean value on click with knockout?

Related Related

  1. 1

    QML: How do you toggle boolean?

  2. 2

    How to make toggle button transparent

  3. 3

    How to make the toggle and the button change if any one of it had changes in different HTML

  4. 4

    How to change the value of a property on toggle button IsChecked?

  5. 5

    How to make visible property work immediately in QML?

  6. 6

    How to make image to fill qml controls button

  7. 7

    How to store multiple Toggle button states in a Boolean Array in Android

  8. 8

    How to bind paper-toggle-button to a Boolean in Polymer

  9. 9

    In awk, how can I make a boolean value that I can toggle it?

  10. 10

    Radio button for boolean property

  11. 11

    make a Toggle button in javascript

  12. 12

    How to toggle a boolean?

  13. 13

    Button toggle div visible property

  14. 14

    How to toggle a Boolean on checkbox in Angularjs

  15. 15

    Using FXML and JavaFX, how do I set a boolean variable using toggle button?

  16. 16

    How to toggle button with value

  17. 17

    how to use toggle in button

  18. 18

    How to toggle keybindings with a button

  19. 19

    Make Image Button Behave Like a Toggle Button

  20. 20

    Java/Android - How can I make a toggle button change state by pressing another button?

  21. 21

    toggle divs left property on button click

  22. 22

    QML: Make property readonly in derived class

  23. 23

    Does any language have a unary boolean toggle operator?

  24. 24

    How to toggle boolean state of react component?

  25. 25

    How to toggle a boolean in postgres in one query

  26. 26

    How do I toggle a boolean array in Python?

  27. 27

    How to toggle boolean value on click with knockout?

  28. 28

    How to toggle a boolean in postgres in one query

  29. 29

    How to toggle boolean value on click with knockout?

HotTag

Archive