Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. is a Switch appropriate here...?
Forum Updated to NodeBB v4.3 + New Features

is a Switch appropriate here...?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
8 Posts 3 Posters 657 Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • mzimmersM Offline
    mzimmersM Offline
    mzimmers
    wrote on last edited by mzimmers
    #1

    Hi all -

    I'm implementing a control system. Several pieces of equipment have on/off switches in their display. At first, it seemed like a (customized) Switch was ideal for this, but now I'm not so sure. When the user clicks one of these controls, I'd like the series of events to occur:

    1. an on/off message is formed and delivered to the controller via a HTTP POST command.
    2. If get a reply to this command that it was successful, I would then (and ONLY then) update the display to show the "on" status, and I would change the checked property of the switch.
    3. If my POST was not successful, I get a 403 response, and I can display an error message. The switch's checked property (and display) should remain unchanged.
      The more I've been experimenting, the more I question whether I really want to use a switch (or, really, any AbstractButton) here. It seems like the automatic interplay between a clicked() and the checked state is different from what I want.

    So...is there some way to partially disable the automatic updating of the checked property (and ensuing display change), or should I just implement my own control with a few rectangles?

    Thanks...

    sierdzioS 1 Reply Last reply
    0
    • mzimmersM mzimmers

      @GrecKo said in is a Switch appropriate here...?:

      Calling your c++ switchIsOn function will prevent the checked property from being updated if the powerState changes.

      OK, maybe I didn't understand your solution as well as I thought.

      My switchIsOn() function doesn't really do anything; it just returns a bool. If I use the binding you posted, what do you expect the toggleOrder() to do?

      To reiterate the data flow:

      • user clicks the switch
      • app sends a message to the controller
      • controller sends a response (either OK or error)
      • upon receiving this response, client sends a GET request
      • upon getting the GET response, client updates the model, including the power state

      It seemed to be working the way I had it, but maybe there's a hidden glitch I can't see. So, do I still need a toggleOrder/switchIsOn function?

      Thanks...

      GrecKoG Offline
      GrecKoG Offline
      GrecKo
      Qt Champions 2018
      wrote on last edited by
      #7

      @mzimmers don't underestimate you, you got most of it the first time!

      You correctly replaced my vague toggleOrder with your actual message sending (sendSwitchChange).
      But I don't think you needed to introduce your switchIsOn function.
      What I had in mind is:

      Toggle {
          id: cardSwitch
          checked: vspCard.powerState === EquipmentNS.POWER_ON
          onToggled: {
              equipmentModel.sendSwitchChange(id, cardSwitch.checked ? EquipmentNS.POWER_ON : EquipmentNS.POWER_OFF)
              checked = Qt.binding(() =>  vspCard.powerState === EquipmentNS.POWER_ON)
          }
      }
      

      Or to factorize it a little:

      Toggle {
          id: cardSwitch
          function switchIsOn() {
              vspCard.powerState === EquipmentNS.POWER_ON
          }
          checked: switchIsOn()
          onToggled: {
              equipmentModel.sendSwitchChange(id, cardSwitch.checked ? EquipmentNS.POWER_ON : EquipmentNS.POWER_OFF)
              checked = Qt.binding(switchIsOn)
          }
      }
      

      Having the function in QML allows the binding to keep being updated if the powerState changes. In c++ your function won't be called again if the NOTIFY signal of the powerState property is emitted.

      mzimmersM 1 Reply Last reply
      1
      • mzimmersM mzimmers

        Hi all -

        I'm implementing a control system. Several pieces of equipment have on/off switches in their display. At first, it seemed like a (customized) Switch was ideal for this, but now I'm not so sure. When the user clicks one of these controls, I'd like the series of events to occur:

        1. an on/off message is formed and delivered to the controller via a HTTP POST command.
        2. If get a reply to this command that it was successful, I would then (and ONLY then) update the display to show the "on" status, and I would change the checked property of the switch.
        3. If my POST was not successful, I get a 403 response, and I can display an error message. The switch's checked property (and display) should remain unchanged.
          The more I've been experimenting, the more I question whether I really want to use a switch (or, really, any AbstractButton) here. It seems like the automatic interplay between a clicked() and the checked state is different from what I want.

        So...is there some way to partially disable the automatic updating of the checked property (and ensuing display change), or should I just implement my own control with a few rectangles?

        Thanks...

        sierdzioS Offline
        sierdzioS Offline
        sierdzio
        Moderators
        wrote on last edited by
        #2

        @mzimmers said in is a Switch appropriate here...?:

        should I just implement my own control with a few rectangles?

        I'd vote for this solution.

        (Z(:^

        GrecKoG 1 Reply Last reply
        1
        • sierdzioS sierdzio

          @mzimmers said in is a Switch appropriate here...?:

          should I just implement my own control with a few rectangles?

          I'd vote for this solution.

          GrecKoG Offline
          GrecKoG Offline
          GrecKo
          Qt Champions 2018
          wrote on last edited by GrecKo
          #3

          Not that pretty but I feel that is still ok: you can reset the checked binding in the onToggled signal handler:

          Switch {
              checked: backend.checked
              onToggled: {
                  checked = Qt.binding(() => backend.checked)
                  backend.toggleOrder()
              }
          }
          

          Note that CheckBox has a nextCheckState function property that can make it somewhat more elegant:

          CheckBox {
              checked: backend.checked
              onReleased: backend.toggleOrder()
              nextCheckState: () => checkState
          }
          

          You can try it with:

          Timer {
              id: backend
              property bool checked: false
              function toggleOrder() {
                  start();
              }
              interval: 500
              onTriggered: checked = !checked
          }
          
          mzimmersM 1 Reply Last reply
          1
          • GrecKoG GrecKo

            Not that pretty but I feel that is still ok: you can reset the checked binding in the onToggled signal handler:

            Switch {
                checked: backend.checked
                onToggled: {
                    checked = Qt.binding(() => backend.checked)
                    backend.toggleOrder()
                }
            }
            

            Note that CheckBox has a nextCheckState function property that can make it somewhat more elegant:

            CheckBox {
                checked: backend.checked
                onReleased: backend.toggleOrder()
                nextCheckState: () => checkState
            }
            

            You can try it with:

            Timer {
                id: backend
                property bool checked: false
                function toggleOrder() {
                    start();
                }
                interval: 500
                onTriggered: checked = !checked
            }
            
            mzimmersM Offline
            mzimmersM Offline
            mzimmers
            wrote on last edited by mzimmers
            #4

            @GrecKo thanks for the suggestion; besides being helpful, it introduced a couple new QML constructs to me.

            I think I understand most of what you're proposing. Here's what I've put together:

            // QML
            Toggle {
                id: cardSwitch
                checked: vspCard.powerState === EquipmentNS.POWER_ON
                onToggled: {
                    equipmentModel.sendSwitchChange(id, cardSwitch.checked ? EquipmentNS.POWER_ON : EquipmentNS.POWER_OFF)
                    checked = Qt.binding(() => equipmentModel.switchIsOn(vspCard.uuid))
                }
            }
            
            // C++ model
            bool EquipmentModel::switchIsOn(QUuid uuid)
            {
                bool rc = false;
                int index = getIndex(uuid);
            
                if (index != NOT_IN_LIST) {
                    Vsp *vsp = static_cast<Vsp *>(m_list->at(index).get());
                    rc = vsp->m_powerState;
                }
                return rc;
            }
            

            (You can ignore all the static_cast stuff; I have to do this because my model's list contains items of different subclasses of Equipment, which is its own headache.)

            Is this what you had in mind? I'm not sure what you wanted me to do with the toggleOrder() call.

            Thanks...

            GrecKoG 1 Reply Last reply
            0
            • mzimmersM mzimmers

              @GrecKo thanks for the suggestion; besides being helpful, it introduced a couple new QML constructs to me.

              I think I understand most of what you're proposing. Here's what I've put together:

              // QML
              Toggle {
                  id: cardSwitch
                  checked: vspCard.powerState === EquipmentNS.POWER_ON
                  onToggled: {
                      equipmentModel.sendSwitchChange(id, cardSwitch.checked ? EquipmentNS.POWER_ON : EquipmentNS.POWER_OFF)
                      checked = Qt.binding(() => equipmentModel.switchIsOn(vspCard.uuid))
                  }
              }
              
              // C++ model
              bool EquipmentModel::switchIsOn(QUuid uuid)
              {
                  bool rc = false;
                  int index = getIndex(uuid);
              
                  if (index != NOT_IN_LIST) {
                      Vsp *vsp = static_cast<Vsp *>(m_list->at(index).get());
                      rc = vsp->m_powerState;
                  }
                  return rc;
              }
              

              (You can ignore all the static_cast stuff; I have to do this because my model's list contains items of different subclasses of Equipment, which is its own headache.)

              Is this what you had in mind? I'm not sure what you wanted me to do with the toggleOrder() call.

              Thanks...

              GrecKoG Offline
              GrecKoG Offline
              GrecKo
              Qt Champions 2018
              wrote on last edited by
              #5

              @mzimmers That's what I had in mind for the toggleOrder (you replacing it with actual backend logic call). But not for the switchIsOn.
              Can't you use the same binding here ?

              checked = Qt.binding(() => vspCard.powerState === EquipmentNS.POWER_ON)
              

              Calling your c++ switchIsOn function will prevent the checked property from being updated if the powerState changes.

              mzimmersM 1 Reply Last reply
              0
              • GrecKoG GrecKo

                @mzimmers That's what I had in mind for the toggleOrder (you replacing it with actual backend logic call). But not for the switchIsOn.
                Can't you use the same binding here ?

                checked = Qt.binding(() => vspCard.powerState === EquipmentNS.POWER_ON)
                

                Calling your c++ switchIsOn function will prevent the checked property from being updated if the powerState changes.

                mzimmersM Offline
                mzimmersM Offline
                mzimmers
                wrote on last edited by
                #6

                @GrecKo said in is a Switch appropriate here...?:

                Calling your c++ switchIsOn function will prevent the checked property from being updated if the powerState changes.

                OK, maybe I didn't understand your solution as well as I thought.

                My switchIsOn() function doesn't really do anything; it just returns a bool. If I use the binding you posted, what do you expect the toggleOrder() to do?

                To reiterate the data flow:

                • user clicks the switch
                • app sends a message to the controller
                • controller sends a response (either OK or error)
                • upon receiving this response, client sends a GET request
                • upon getting the GET response, client updates the model, including the power state

                It seemed to be working the way I had it, but maybe there's a hidden glitch I can't see. So, do I still need a toggleOrder/switchIsOn function?

                Thanks...

                GrecKoG 1 Reply Last reply
                0
                • mzimmersM mzimmers

                  @GrecKo said in is a Switch appropriate here...?:

                  Calling your c++ switchIsOn function will prevent the checked property from being updated if the powerState changes.

                  OK, maybe I didn't understand your solution as well as I thought.

                  My switchIsOn() function doesn't really do anything; it just returns a bool. If I use the binding you posted, what do you expect the toggleOrder() to do?

                  To reiterate the data flow:

                  • user clicks the switch
                  • app sends a message to the controller
                  • controller sends a response (either OK or error)
                  • upon receiving this response, client sends a GET request
                  • upon getting the GET response, client updates the model, including the power state

                  It seemed to be working the way I had it, but maybe there's a hidden glitch I can't see. So, do I still need a toggleOrder/switchIsOn function?

                  Thanks...

                  GrecKoG Offline
                  GrecKoG Offline
                  GrecKo
                  Qt Champions 2018
                  wrote on last edited by
                  #7

                  @mzimmers don't underestimate you, you got most of it the first time!

                  You correctly replaced my vague toggleOrder with your actual message sending (sendSwitchChange).
                  But I don't think you needed to introduce your switchIsOn function.
                  What I had in mind is:

                  Toggle {
                      id: cardSwitch
                      checked: vspCard.powerState === EquipmentNS.POWER_ON
                      onToggled: {
                          equipmentModel.sendSwitchChange(id, cardSwitch.checked ? EquipmentNS.POWER_ON : EquipmentNS.POWER_OFF)
                          checked = Qt.binding(() =>  vspCard.powerState === EquipmentNS.POWER_ON)
                      }
                  }
                  

                  Or to factorize it a little:

                  Toggle {
                      id: cardSwitch
                      function switchIsOn() {
                          vspCard.powerState === EquipmentNS.POWER_ON
                      }
                      checked: switchIsOn()
                      onToggled: {
                          equipmentModel.sendSwitchChange(id, cardSwitch.checked ? EquipmentNS.POWER_ON : EquipmentNS.POWER_OFF)
                          checked = Qt.binding(switchIsOn)
                      }
                  }
                  

                  Having the function in QML allows the binding to keep being updated if the powerState changes. In c++ your function won't be called again if the NOTIFY signal of the powerState property is emitted.

                  mzimmersM 1 Reply Last reply
                  1
                  • mzimmersM mzimmers has marked this topic as solved on
                  • GrecKoG GrecKo

                    @mzimmers don't underestimate you, you got most of it the first time!

                    You correctly replaced my vague toggleOrder with your actual message sending (sendSwitchChange).
                    But I don't think you needed to introduce your switchIsOn function.
                    What I had in mind is:

                    Toggle {
                        id: cardSwitch
                        checked: vspCard.powerState === EquipmentNS.POWER_ON
                        onToggled: {
                            equipmentModel.sendSwitchChange(id, cardSwitch.checked ? EquipmentNS.POWER_ON : EquipmentNS.POWER_OFF)
                            checked = Qt.binding(() =>  vspCard.powerState === EquipmentNS.POWER_ON)
                        }
                    }
                    

                    Or to factorize it a little:

                    Toggle {
                        id: cardSwitch
                        function switchIsOn() {
                            vspCard.powerState === EquipmentNS.POWER_ON
                        }
                        checked: switchIsOn()
                        onToggled: {
                            equipmentModel.sendSwitchChange(id, cardSwitch.checked ? EquipmentNS.POWER_ON : EquipmentNS.POWER_OFF)
                            checked = Qt.binding(switchIsOn)
                        }
                    }
                    

                    Having the function in QML allows the binding to keep being updated if the powerState changes. In c++ your function won't be called again if the NOTIFY signal of the powerState property is emitted.

                    mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #8

                    @GrecKo thanks for the clarification. I've implemented your approach and verified that it works. (It actually helped me uncover a minor bug where power state was kept as an enum, but received from the core as a bool, causing the "===" to fail. Took me a few minutes to find that one!)

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved