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. endMoveRows in model crashes my app
Forum Updated to NodeBB v4.3 + New Features

endMoveRows in model crashes my app

Scheduled Pinned Locked Moved Solved QML and Qt Quick
8 Posts 5 Posters 2.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.
  • M Offline
    M Offline
    Marek
    wrote on last edited by
    #1

    Hi
    I need to move items inside custom QAbstractListModel, this works with ListModel.move()
    Code is like this

    void ObjectModel::move(int from, int to) {
        if(from==to || to==modelVector.count()-1 || from==0)
            return;
    
        beginMoveRows(QModelIndex(),from,from,QModelIndex(),to);
        modelVector.move(from,to);
        endMoveRows();
    

    The thing is that it crashes when I move up from 2 to 3.
    I have read about no-op moves here:
    http://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows
    Does this mean that I can't move items up ? or up by one place ?

    Best,
    Marek

    M 1 Reply Last reply
    0
    • M Marek

      Hi
      I need to move items inside custom QAbstractListModel, this works with ListModel.move()
      Code is like this

      void ObjectModel::move(int from, int to) {
          if(from==to || to==modelVector.count()-1 || from==0)
              return;
      
          beginMoveRows(QModelIndex(),from,from,QModelIndex(),to);
          modelVector.move(from,to);
          endMoveRows();
      

      The thing is that it crashes when I move up from 2 to 3.
      I have read about no-op moves here:
      http://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows
      Does this mean that I can't move items up ? or up by one place ?

      Best,
      Marek

      M Offline
      M Offline
      Marek
      wrote on last edited by
      #2

      Ok I got this working by simple hack

      void ObjectModel::move(int from, int to) {
          if(from+1==to) {
              to++;
              if(to>modelVector.count()-1)
                  to=modelVector.count()-1;
          }
          if(from==to || from+1==to)
              return;
      
          beginMoveRows(QModelIndex(),from,from,QModelIndex(),to);
          modelVector.move(from,to);
          endMoveRows();
      

      Best,
      Marek

      1 Reply Last reply
      0
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by VRonin
        #3

        The arguments to beginMoveRows when parents are the same are not trivial at all. See this commit that will be part of Qt 5.13 for an example of how to implement it.

        beginMoveRows returns a bool so you should always check it

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        M 1 Reply Last reply
        1
        • VRoninV VRonin

          The arguments to beginMoveRows when parents are the same are not trivial at all. See this commit that will be part of Qt 5.13 for an example of how to implement it.

          beginMoveRows returns a bool so you should always check it

          M Offline
          M Offline
          Marek
          wrote on last edited by
          #4

          @VRonin thanks for the hint with return value.
          Somehow I have managed to make app work without crash.
          How should I view this link you have provided to see how to implement it ;)

          Best,
          Marek

          VRoninV 1 Reply Last reply
          0
          • M Marek

            @VRonin thanks for the hint with return value.
            Somehow I have managed to make app work without crash.
            How should I view this link you have provided to see how to implement it ;)

            Best,
            Marek

            VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #5

            @Marek said in endMoveRows in model crashes my app:

            How should I view this link you have provided to see how to implement it

            More precise link: https://codereview.qt-project.org/#/c/237801/5/src/widgets/itemviews/qlistwidget.cpp

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            P 1 Reply Last reply
            2
            • VRoninV VRonin

              @Marek said in endMoveRows in model crashes my app:

              How should I view this link you have provided to see how to implement it

              More precise link: https://codereview.qt-project.org/#/c/237801/5/src/widgets/itemviews/qlistwidget.cpp

              P Offline
              P Offline
              patrickkidd
              wrote on last edited by
              #6

              @VRonin It seems to me that beginMoveRows would prevent return false for attempting to move row 0 to row 1 in a list of two elements. The call would look like:

              beginMoveRows(QModelIndex(), 0, 0, QModelIndex(), 1)

              I have read the documentation for beginMoveRows a few times and can't for the life of me understand the rules for these indexes. Even with the visual diagrams provided. I do know that if(newRow > oldRow) newRow++ makes it work.

              Can anyone help me understand how to determine the correct indexes to pass?

              Thanks!

              https://alaskafamilysystems.com/

              N 1 Reply Last reply
              0
              • P patrickkidd

                @VRonin It seems to me that beginMoveRows would prevent return false for attempting to move row 0 to row 1 in a list of two elements. The call would look like:

                beginMoveRows(QModelIndex(), 0, 0, QModelIndex(), 1)

                I have read the documentation for beginMoveRows a few times and can't for the life of me understand the rules for these indexes. Even with the visual diagrams provided. I do know that if(newRow > oldRow) newRow++ makes it work.

                Can anyone help me understand how to determine the correct indexes to pass?

                Thanks!

                N Offline
                N Offline
                Nonalcogolic
                wrote on last edited by
                #7

                @patrickkidd said in endMoveRows in model crashes my app:

                if(newRow > oldRow) newRow++

                Seems that the QT holds the place of your element while it's not completely moved down to new place.
                So when you are trying to move elem '0' down after '1' and use beginMoveRows(QModelIndex(), 0, 0, QModelIndex(), 1):

                0
                1
                2
                

                It will have an intermediate state with one additional cell:

                0 (where the original value has been stored) 
                0 (new place for 0 element matched to the index you mentioned with last param in beginMoveRows) 
                1 
                2
                

                Afterwards the original cell '0' will be removed. Still not clear why it should cause app crush.. but this is not going to give you an expected profit anyway.

                1 Reply Last reply
                0
                • I Offline
                  I Offline
                  i23a
                  wrote on last edited by
                  #8

                  I think it crashes because move up from 2 to 3 equals to do nothing.
                  According to doc https://doc.qt.io/qt-5/qabstractitemmodel.html#beginMoveRows
                  If you want to move 2 to 3 you have to move 2 to 4, but in this case you will have a problem with pre_last & last element.
                  So there is a tricky way to do that: move 3 to 2

                  void ObjectModel::move(int from, int to) {
                  ...
                  if (from + 1 == to)
                    std::swap(from, to);
                  
                  beginMoveRows(QModelIndex(),from,from,QModelIndex(),to);
                  ...
                  endMoveRows();
                  }
                  
                  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