Results 1 to 13 of 13

Thread: beginMoveRows corrupting persistent model indexes

  1. #1
    Join Date
    Jul 2008
    Posts
    14
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Unhappy beginMoveRows corrupting persistent model indexes

    Hi everyone,

    I am coding an application that needs to show items using a QTableView, so I subclassed QAbstractItemModel to allow handling of the data without duplication. (My data is stored into a QList using pointers)

    I store this pointer into a custom role in each row element (the user can only move rows, not separate items).

    When moving items using drag & drop I obtain this assert fail :
    Qt Code:
    1. ASSERT failure in QPersistentModelIndex::~QPersistentModelIndex: "persistent model indexes corrupted", file kernel\qabstractitemmodel.cpp, line 544
    To copy to clipboard, switch view to plain text mode 

    There are few usage examples of the beginMoveRows and endMoveRows methods because it's quite new (4.6), but I think I used it correctly, so the problem must be somewhere else...

    This is the code where I use this methods :
    Qt Code:
    1. if(!beginMoveRows(QModelIndex(), rowId, rowId, QModelIndex(), position))
    2. continue;
    3. mScript->moveAction(rowId, position);
    4. endMoveRows();
    To copy to clipboard, switch view to plain text mode 
    mScript is my QList with pointers, and I use the move method.

    Please say I you need more extracts...
    Coding for Actionaz 3

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: beginMoveRows corrupting persistent model indexes

    What does moveAction() do? What values get passed as rowId and position?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  3. #3
    Join Date
    Jul 2008
    Posts
    14
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: beginMoveRows corrupting persistent model indexes

    Here is the code, I think it's better than a description

    Qt Code:
    1. void Script::moveAction(int startLine, int endLine)
    2. {
    3. if(startLine < 0 || startLine >= mActions.count() ||
    4. endLine < 0 || startLine == endLine)
    5. return;
    6.  
    7. if(endLine >= mActions.count())
    8. mActions.append(mActions.takeAt(startLine));
    9. else
    10. mActions.move(startLine, endLine);
    11. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. QList<Action *> mActions;
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. bool ScriptModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
    2. {
    3. if(action == Qt::IgnoreAction)
    4. return true;
    5.  
    6. if(column > 3 || parent.isValid())
    7. return false;
    8.  
    9. int position;
    10.  
    11. if(row != -1)
    12. position = row;
    13. else
    14. position = rowCount(QModelIndex());
    15.  
    16. QByteArray encodedData = data->data("application/act.action");
    17. QDataStream stream(&encodedData, QIODevice::ReadOnly);
    18.  
    19. QList<int> rowIdList;
    20. while(!stream.atEnd())
    21. {
    22. QString text;
    23. stream >> text;
    24. rowIdList << text.toInt();
    25. }
    26.  
    27. foreach(int rowId, rowIdList)
    28. {
    29. Action *originalAction = mScript->actionAt(rowId);
    30. if(!originalAction)
    31. continue;
    32.  
    33. if(rowId == position)
    34. continue;
    35.  
    36. if(!beginMoveRows(QModelIndex(), rowId, rowId, QModelIndex(), position))
    37. continue;
    38. mScript->moveAction(rowId, position);
    39. endMoveRows();
    40. }
    41. return true;
    42. }
    To copy to clipboard, switch view to plain text mode 

    I know this would probably fail when moving multiple items because if the lower item is moved before the row ids will not be valid any more. But this asserts even for the first one so that is probably not the problem.
    Coding for Actionaz 3

  4. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: beginMoveRows corrupting persistent model indexes

    If row equals -1 then your code will fail. rowCount() is larger by one than maximum allowed index (row number) of an element. Moving items doesn't increase the count, so the maximum allowed row number is rowCount()-1.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  5. #5
    Join Date
    Jul 2008
    Posts
    14
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: beginMoveRows corrupting persistent model indexes

    True, but I have this assert on any operation, even when I move an item from row 1 to row 0 when 3 items are in the list.
    Coding for Actionaz 3

  6. #6
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: beginMoveRows corrupting persistent model indexes

    Back to my original question - what are the parameters passed to those methods? Please use a debugger or qDebug statements to dump them. I wouldn't be surprised if row was always -1
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  7. #7
    Join Date
    Jul 2008
    Posts
    14
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: beginMoveRows corrupting persistent model indexes

    I added a qDebug at the start of dropMimeData.
    All the tests are done with 3 items in the list.

    When moving from position 0 to position 1 :
    Qt Code:
    1. row= 2 column= 1 parent= QModelIndex(-1,-1,0x0,QObject(0x0) )
    To copy to clipboard, switch view to plain text mode 
    When moving from position 1 to position 0 :
    Qt Code:
    1. row= 0 column= 1 parent= QModelIndex(-1,-1,0x0,QObject(0x0) )
    To copy to clipboard, switch view to plain text mode 
    When moving from position 0 to position 3 : (after the last element)
    Qt Code:
    1. row= -1 column= -1 parent= QModelIndex(-1,-1,0x0,QObject(0x0) )
    To copy to clipboard, switch view to plain text mode 

    I get the assert in the first two cases, and I return false when row == -1.
    Coding for Actionaz 3

  8. #8
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: beginMoveRows corrupting persistent model indexes

    Please provide a minimal compilable example reproducing the problem. You are using 4.6.0 stable, right?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. #9
    Join Date
    Jul 2008
    Posts
    14
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: beginMoveRows corrupting persistent model indexes

    Here is a minimal sample attached. Yes I use the 4.6 stable.

    I think I found the problem, I use the ModelTest from http://labs.trolltech.com/page/Proje...view/Modeltest, and there seems to be some conflict between ModelTest and beginMoveRows... When deactivating it (by commenting the new ModelTest(sm, this); row in mainwindow.cpp no more asserts appear)

    Do you think I made something wrong ? Or is it a ModelTest bug ?
    Attached Files Attached Files
    Coding for Actionaz 3

  10. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: beginMoveRows corrupting persistent model indexes

    ModelTest was not meant to be used with moveRows() as the latter was introduced with 4.6. By the way... is this really a minimal example?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. The following user says thank you to wysota for this useful post:

    Jmgr (19th December 2009)

  12. #11
    Join Date
    Jul 2008
    Posts
    14
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: beginMoveRows corrupting persistent model indexes

    Ok, then my problem is fixed, thanks for your help !

    By the way... is this really a minimal example?
    Well... I wasn't sure where the problem was, so I included the whole Script stuff. But yes, I could have removed it since it was clearly a ModelTest issue, sorry.
    Coding for Actionaz 3

  13. #12
    Join Date
    Jul 2008
    Posts
    14
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: beginMoveRows corrupting persistent model indexes

    Hm, I found something strange within the private QAbstractItemModelPrivate::allowMove method in Qt.

    Qt Code:
    1. // Don't move the range within itself.
    2. if (destinationParent == srcParent)
    3. return !(destinationStart >= start && destinationStart <= end + 1);
    To copy to clipboard, switch view to plain text mode 
    I don't understand the + 1 here, because this is preventing the move of an item from position 0 to position 1...

    I this case destinationStart is == 1, start and end are == 0, so this method returns false, but the move operation seems to be valid.

    I tried removing the + 1 and everything goes fine. But I don't want to edit Qt to be able to move an item from position 0 to position 1

    *Could* this be a bug in Qt ?
    Coding for Actionaz 3

  14. #13
    Join Date
    Jan 2011
    Posts
    18
    Thanks
    6
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Android

    Default Re: beginMoveRows corrupting persistent model indexes

    i know this thread is quite old, but i may help others...

    Quote Originally Posted by Jmgr View Post
    *Could* this be a bug in Qt ?
    This isn't a bug, see http://bugreports.qt.nokia.com/browse/QTBUG-6940

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.