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. Why is this a binding loop?
Forum Updated to NodeBB v4.3 + New Features

Why is this a binding loop?

Scheduled Pinned Locked Moved Solved QML and Qt Quick
14 Posts 4 Posters 2.3k Views 2 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 mzimmers

    Hi all -

    I have a class with the following in it:

    Q_PROPERTY( QStringList posterModalChecklist
    	MEMBER m_posterModalChecklist
    	READ GetPosterModalChecklist
            NOTIFY EventPosterModalChecklistChangedForQML )
    			
    QStringList m_posterModalChecklist;
    void EventPosterModalChecklistChangedForQML(QStringList qsl);
      
    QStringList ChangeConsumables::GetPosterModalChecklist() {
      m_posterModalChecklist = m_batch[m_index]->PosterModalChecklist();
      emit EventPosterModalChecklistChangedForQML(m_posterModalChecklist);
      return m_posterModalChecklist;
    }
    

    Used in this QML:

    Column {
      Repeater {
    	model: changeConsumablesViewModel.posterModalChecklist
    	RowLayout {
    	  Label {
    		text: modelData
    

    At runtime I get an error about a binding loop on "model." The error was introduced when I put in the emit() call. What might I be doing wrong?

    Thanks...

    KroMignonK Offline
    KroMignonK Offline
    KroMignon
    wrote on last edited by
    #3

    @mzimmers said in Why is this a binding loop?:

    At runtime I get an error about a binding loop on "model." The error was introduced when I put in the emit() call. What might I be doing wrong?

    First you should understand how binding loops are detected, therefore take a look at this video from KDAB: Introduction to Qt / QML (Part 11) - Binding Loops.

    Now to solve your issue: remove the emit in the getter. You should only emit a notification on property value change, the purpose of this is to enable QML to be aware about changes. So property changes on C++ side can automatically trigger updates on QML side.
    If you trigger notification in C++ side with the getter, then:

    1. QML is reading property with getter
    2. QML is notified about property value change
    3. QML reread property value with getter
    4. QML is notified about property value change
    5. QML detect binding loop!

    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

    1 Reply Last reply
    6
    • mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on last edited by
      #4

      Thank you both for the help. To answer your question about why there was a signal on a get -- the way this app was written, the get not only returned the current value, but also updated it first (I know it's weird).

      To fix this, I've created a setter for the property:

      QStringList ChangeConsumables::GetPosterModalChecklist() {
        return m_posterModalChecklist;
      }
      
      void ChangeConsumables::SetPosterModalChecklist(QStringList qsl) {
        m_posterModalChecklist = qsl;
        emit EventPosterModalChecklistChangedForQML(m_posterModalChecklist);
      }
      

      The code is a little convoluted, as the setter is actually invoked by another object (the same one that's providing the QStringList to the getter), but it seems to work.

      Thanks again...

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #5

        Hi,

        There's one thing missing from your setter: the equality guard. Usually the first thing done in a setter is check if the value changes and stop there if not. This allows to avoid signal storms were each party connected re-emits the same values over and over.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        mzimmersM 1 Reply Last reply
        3
        • SGaistS SGaist

          Hi,

          There's one thing missing from your setter: the equality guard. Usually the first thing done in a setter is check if the value changes and stop there if not. This allows to avoid signal storms were each party connected re-emits the same values over and over.

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

          @SGaist so, like this?

          void ChangeConsumables::SetPosterModalChecklist(QStringList qsl) {
            if (m_posterModalChecklist != qsl) {
                m_posterModalChecklist = qsl;
                emit EventPosterModalChecklistChangedForQML(m_posterModalChecklist);
            }
          }
          
          1 Reply Last reply
          1
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #7

            Either that or

            void ChangeConsumables::SetPosterModalChecklist(QStringList qsl) {
              if (m_posterModalChecklist == qsl) {
                  return;
            }
              m_posterModalChecklist = qsl;
              emit EventPosterModalChecklistChangedForQML(m_posterModalChecklist);
            }
            

            Depending on your taste.
            Note that I have seen this version more frequently. Also in Qt's own sources.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            mzimmersM 1 Reply Last reply
            2
            • SGaistS SGaist

              Either that or

              void ChangeConsumables::SetPosterModalChecklist(QStringList qsl) {
                if (m_posterModalChecklist == qsl) {
                    return;
              }
                m_posterModalChecklist = qsl;
                emit EventPosterModalChecklistChangedForQML(m_posterModalChecklist);
              }
              

              Depending on your taste.
              Note that I have seen this version more frequently. Also in Qt's own sources.

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

              @SGaist I realize I'm old school, but I really don't like return statements in the middle of a function. I know it's done by far better coders than I, but I'm just not a fan.

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #9

                I understand your point.

                IIRC, early returns like these may allow some optimization by the compiler.

                It's technically also at least one less operation because != is usually implemented as ! ==.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • mzimmersM Offline
                  mzimmersM Offline
                  mzimmers
                  wrote on last edited by
                  #10

                  Not to be argumentative, but I'd venture that a routine that is comparing QStringList objects probably leaves much to be desired in the optimization department anyway.

                  Your comment about !== is interesting. Is there a way for the programmer to explicitly effect a similar comparison?

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #11

                    @mzimmers said in Why is this a binding loop?:

                    Not to be argumentative, but I'd venture that a routine that is comparing QStringList objects probably leaves much to be desired in the optimization department anyway.

                    I was more in the generic case of simple type comparison :-)

                    @mzimmers said in Why is this a binding loop?:

                    Your comment about !== is interesting. Is there a way for the programmer to explicitly effect a similar comparison?

                    I am not sure I am following you on that one.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    mzimmersM 1 Reply Last reply
                    0
                    • SGaistS SGaist

                      @mzimmers said in Why is this a binding loop?:

                      Not to be argumentative, but I'd venture that a routine that is comparing QStringList objects probably leaves much to be desired in the optimization department anyway.

                      I was more in the generic case of simple type comparison :-)

                      @mzimmers said in Why is this a binding loop?:

                      Your comment about !== is interesting. Is there a way for the programmer to explicitly effect a similar comparison?

                      I am not sure I am following you on that one.

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

                      @SGaist said in Why is this a binding loop?:

                      I am not sure I am following you on that one.

                      Well, of course C++ doesn't have a "!==" operator, so I assumed you meant that it first compares type, then content (a la Javascript). I was just curious how a C++ coder might perform that type check explicitly.

                      1 Reply Last reply
                      0
                      • SGaistS Offline
                        SGaistS Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on last edited by
                        #13

                        You missed the space between the ! and the == :-)

                        I meant it as: "!(a == b)"

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0
                        • mzimmersM Offline
                          mzimmersM Offline
                          mzimmers
                          wrote on last edited by mzimmers
                          #14

                          Oh...I hate it when I do that (heh).

                          But now my statement on efficiency is even more true...

                          EDIT:

                          For those who really wish to exact that last bit of optimization, you could always do something like this:

                          void ChangeConsumables::SetPosterModalChecklist(QStringList qsl) {
                            do {
                              if (m_posterModalChecklist == qsl) {
                                continue;
                              }
                              if (any other reasons to exclude further processing) {
                                continue;
                              }
                              m_posterModalChecklist = qsl;
                              emit EventPosterModalChecklistChangedForQML(m_posterModalChecklist);
                            } while (false);
                          }
                          

                          This technique is also very handy for avoiding multiple if statements (with their annoying attendant indentation).

                          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