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. spinBox value is unbind
Qt 6.11 is out! See what's new in the release blog

spinBox value is unbind

Scheduled Pinned Locked Moved Solved QML and Qt Quick
11 Posts 3 Posters 1.4k Views 1 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.
  • I Offline
    I Offline
    Idodoqdo
    wrote on last edited by aha_1980
    #1

    I have bind the model value to speenBox

            SpinBox {
               id: spinbox
               Layout.preferredWidth: parent.width * 0.3
    
               from: 0
               value: val
               to: 100
    
               validator: DoubleValidator {
                   bottom: Math.min(spinbox.from, spinbox.to)
                   top:  Math.max(spinbox.from, spinbox.to)
               }
    
               onValueChanged: {
                 val = value
               }
            }
    

    A loop appeared, but I prevented it as follows:

    bool CameraConfigurationSettingsModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
        int row = index.row();
    
        if (row < 0 || row >= settings_.count()) {
            return false;
        }
    
        CameraConfigurationSetting& setting = settings_[row];
    
        switch (role) {
            case valueRole:
                if (setting.GetValue() == value.toDouble()) { // here
                    return false;
                }
                setting.SetValue(value.toDouble());
                emit dataChanged(index, index);
                return true;
            case switchedRole:
                setting.Switch();
                emit dataChanged(index, index);
                return true;
        }
    
        return false;
    }
    

    By changing the value in SpeenBox using the up and down arrows, changing the value does not affect the binding, but if I write a value in the field, then after that it will be unlinked. help me please

    sierdzioS 1 Reply Last reply
    0
    • I Idodoqdo

      I have bind the model value to speenBox

              SpinBox {
                 id: spinbox
                 Layout.preferredWidth: parent.width * 0.3
      
                 from: 0
                 value: val
                 to: 100
      
                 validator: DoubleValidator {
                     bottom: Math.min(spinbox.from, spinbox.to)
                     top:  Math.max(spinbox.from, spinbox.to)
                 }
      
                 onValueChanged: {
                   val = value
                 }
              }
      

      A loop appeared, but I prevented it as follows:

      bool CameraConfigurationSettingsModel::setData(const QModelIndex &index, const QVariant &value, int role)
      {
          int row = index.row();
      
          if (row < 0 || row >= settings_.count()) {
              return false;
          }
      
          CameraConfigurationSetting& setting = settings_[row];
      
          switch (role) {
              case valueRole:
                  if (setting.GetValue() == value.toDouble()) { // here
                      return false;
                  }
                  setting.SetValue(value.toDouble());
                  emit dataChanged(index, index);
                  return true;
              case switchedRole:
                  setting.Switch();
                  emit dataChanged(index, index);
                  return true;
          }
      
          return false;
      }
      

      By changing the value in SpeenBox using the up and down arrows, changing the value does not affect the binding, but if I write a value in the field, then after that it will be unlinked. help me please

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

      @Idodoqdo this is a standard problem in QML stemming from a conflict between declarative and imperative ways of operation and there are a few ways around it.

      One is to use a 2-way binding, see for example this presentation from KDAB about it: link.

      Another would be to not set the binding at all, but rather react in slots to both onValueChanged (when user changes the value) and onValChanged (when the model is updated).

      (Z(:^

      I 1 Reply Last reply
      0
      • sierdzioS sierdzio

        @Idodoqdo this is a standard problem in QML stemming from a conflict between declarative and imperative ways of operation and there are a few ways around it.

        One is to use a 2-way binding, see for example this presentation from KDAB about it: link.

        Another would be to not set the binding at all, but rather react in slots to both onValueChanged (when user changes the value) and onValChanged (when the model is updated).

        I Offline
        I Offline
        Idodoqdo
        wrote on last edited by
        #3

        @sierdzio and how will the display understand that the changes relate specifically to this model? Can you please suggest sources that will help me do the 2nd method?

        sierdzioS 1 Reply Last reply
        0
        • I Idodoqdo

          @sierdzio and how will the display understand that the changes relate specifically to this model? Can you please suggest sources that will help me do the 2nd method?

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

          @Idodoqdo said in speenBox value is unbind:

          @sierdzio and how will the display understand that the changes relate specifically to this model? Can you please suggest sources that will help me do the 2nd method?

          You will set value in the slots, so it will be updated in the UI right away.

          (Z(:^

          I 2 Replies Last reply
          0
          • sierdzioS sierdzio

            @Idodoqdo said in speenBox value is unbind:

            @sierdzio and how will the display understand that the changes relate specifically to this model? Can you please suggest sources that will help me do the 2nd method?

            You will set value in the slots, so it will be updated in the UI right away.

            I Offline
            I Offline
            Idodoqdo
            wrote on last edited by
            #5

            @sierdzio I'm new to qml, so I don't know how to do onValChanged

            1 Reply Last reply
            0
            • sierdzioS sierdzio

              @Idodoqdo said in speenBox value is unbind:

              @sierdzio and how will the display understand that the changes relate specifically to this model? Can you please suggest sources that will help me do the 2nd method?

              You will set value in the slots, so it will be updated in the UI right away.

              I Offline
              I Offline
              Idodoqdo
              wrote on last edited by
              #6

              @sierdzio

              how to make Connections if I don't have a model in the component. Only roles?

              Item {
                  id:cell
              
                  RowLayout {
                      spacing: 0
                      anchors.fill: parent
                      Rectangle {
                          border.color: "black"
                          color: "black"
                          Layout.preferredWidth: parent.width * 0.2
                          Layout.fillHeight: true
                          Switch {
                              checked: switched
                              anchors.centerIn: parent
                              visible: isHaveSwitch
                              Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
                              onClicked: {
                                  switched = !switched
                              }
              
                          }
                      }
                      Rectangle {
                          color: "black"
                          Layout.fillWidth:  true
                          Layout.fillHeight: true
                          Text {
                              font.bold: true
                              color: "white"
                              text: name
                              anchors.left: parent.left
                              anchors.verticalCenter: parent.verticalCenter
              
                          }
                      }
              
                      SpinBox {
                         id: spinbox
                         Layout.preferredWidth: parent.width * 0.3
              
                         from: 0
                         value: val
                         to: 100
              
                         validator: DoubleValidator {
                             bottom: Math.min(spinbox.from, spinbox.to)
                             top:  Math.max(spinbox.from, spinbox.to)
                         }
              
                         onValueChanged: {
                           val = value
                         }
              
                      }
                  }
              }
              
              sierdzioS 1 Reply Last reply
              0
              • I Idodoqdo

                @sierdzio

                how to make Connections if I don't have a model in the component. Only roles?

                Item {
                    id:cell
                
                    RowLayout {
                        spacing: 0
                        anchors.fill: parent
                        Rectangle {
                            border.color: "black"
                            color: "black"
                            Layout.preferredWidth: parent.width * 0.2
                            Layout.fillHeight: true
                            Switch {
                                checked: switched
                                anchors.centerIn: parent
                                visible: isHaveSwitch
                                Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
                                onClicked: {
                                    switched = !switched
                                }
                
                            }
                        }
                        Rectangle {
                            color: "black"
                            Layout.fillWidth:  true
                            Layout.fillHeight: true
                            Text {
                                font.bold: true
                                color: "white"
                                text: name
                                anchors.left: parent.left
                                anchors.verticalCenter: parent.verticalCenter
                
                            }
                        }
                
                        SpinBox {
                           id: spinbox
                           Layout.preferredWidth: parent.width * 0.3
                
                           from: 0
                           value: val
                           to: 100
                
                           validator: DoubleValidator {
                               bottom: Math.min(spinbox.from, spinbox.to)
                               top:  Math.max(spinbox.from, spinbox.to)
                           }
                
                           onValueChanged: {
                             val = value
                           }
                
                        }
                    }
                }
                
                sierdzioS Offline
                sierdzioS Offline
                sierdzio
                Moderators
                wrote on last edited by
                #7

                @Idodoqdo that is a very good question. You can emit a signal in the model and then make Connections to the model itself.
                Or you can return a QObject from your model (in one of the roles) and have your signal there (and connect to it).

                (Z(:^

                I 1 Reply Last reply
                0
                • sierdzioS sierdzio

                  @Idodoqdo that is a very good question. You can emit a signal in the model and then make Connections to the model itself.
                  Or you can return a QObject from your model (in one of the roles) and have your signal there (and connect to it).

                  I Offline
                  I Offline
                  Idodoqdo
                  wrote on last edited by
                  #8

                  @sierdzio
                  in the 2nd case, should the elements of my QAbstractListModel be inherited from QObject?If these are ordinary objects, then only in the first way. Thanks

                  sierdzioS 1 Reply Last reply
                  0
                  • I Idodoqdo

                    @sierdzio
                    in the 2nd case, should the elements of my QAbstractListModel be inherited from QObject?If these are ordinary objects, then only in the first way. Thanks

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

                    @Idodoqdo said in spinBox value is unbind:

                    @sierdzio
                    in the 2nd case, should the elements of my QAbstractListModel be inherited from QObject?If these are ordinary objects, then only in the first way. Thanks

                    Yes, either Q_OBJECT or Q_GADGET, only such objects are visible to QML.

                    Well ok technically you can return a QVariantMap, too and it "looks" like an object in QML, but it is a hacky solution.

                    (Z(:^

                    GrecKoG 1 Reply Last reply
                    0
                    • sierdzioS sierdzio

                      @Idodoqdo said in spinBox value is unbind:

                      @sierdzio
                      in the 2nd case, should the elements of my QAbstractListModel be inherited from QObject?If these are ordinary objects, then only in the first way. Thanks

                      Yes, either Q_OBJECT or Q_GADGET, only such objects are visible to QML.

                      Well ok technically you can return a QVariantMap, too and it "looks" like an object in QML, but it is a hacky solution.

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

                      All that shouldn't be needed, SpinBox already supports not breaking bindings:

                      ListModel {
                              id: listModel
                              ListElement {
                                  val: 12
                              }
                              ListElement {
                                  val: 33
                              }
                          }
                      
                          Row {
                              anchors.centerIn: parent
                              spacing: 10
                              Repeater {
                                  model: 2
                                  Column {
                                      Repeater {
                                          model: listModel
                                          SpinBox {
                                              id: spinbox
                                              editable: true
                                              from: 0
                                              to: 50
                                              value: val
                                              onValueModified: val = value
                                              validator: DoubleValidator {
                                                  bottom: Math.min(spinbox.from, spinbox.to)
                                                  top:  Math.max(spinbox.from, spinbox.to)
                                              }
                                          }
                                      }
                                  }
                              }
                          }
                      

                      Prefer using the interaction signal valueModified than the raw signal valueChanged to only catch changes from user interactions and not those from backend bindings like the loop you had before.

                      I 1 Reply Last reply
                      0
                      • GrecKoG GrecKo

                        All that shouldn't be needed, SpinBox already supports not breaking bindings:

                        ListModel {
                                id: listModel
                                ListElement {
                                    val: 12
                                }
                                ListElement {
                                    val: 33
                                }
                            }
                        
                            Row {
                                anchors.centerIn: parent
                                spacing: 10
                                Repeater {
                                    model: 2
                                    Column {
                                        Repeater {
                                            model: listModel
                                            SpinBox {
                                                id: spinbox
                                                editable: true
                                                from: 0
                                                to: 50
                                                value: val
                                                onValueModified: val = value
                                                validator: DoubleValidator {
                                                    bottom: Math.min(spinbox.from, spinbox.to)
                                                    top:  Math.max(spinbox.from, spinbox.to)
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        

                        Prefer using the interaction signal valueModified than the raw signal valueChanged to only catch changes from user interactions and not those from backend bindings like the loop you had before.

                        I Offline
                        I Offline
                        Idodoqdo
                        wrote on last edited by
                        #11

                        @GrecKo Thank you. I will try

                        1 Reply Last reply
                        0
                        • I Idodoqdo has marked this topic as solved on

                        • Login

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