Results 1 to 11 of 11

Thread: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

  1. #1
    Join Date
    Sep 2013
    Location
    Moscow
    Posts
    9
    Qt products
    Qt5
    Platforms
    Windows

    Default QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    Hi,

    I have successfully implemented QTreeView + QAbstractItemModel (both subclassed) tree, and insertRows works fine - puts new rows where I expect with no problems.

    Now I need to add filtering to this construction. I add my QSortFilterProxyModel subclass between view and model and it filters fine too.
    But here I have a problem with insertRows - it just crashes, and debugging doesn't help much.

    I would appreciate some working example of such construction - "QTreeView + QAbstractItemModel + QSortFilterProxyModel + insertRows".
    Or maybe a link to documentation part, that explains how QAbstractItemModel and QSortFilterProxyModel work together when I need to add a row.

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    Why doesn't the debugger help much?
    If you run in the debugger you should get exactly the crashing line, this usually is more then enough to know what the problem is.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Sep 2013
    Location
    Moscow
    Posts
    9
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    Well... it may be a bit long to explain... It behaves unexpectedly somehow, for example:


    Qt Code:
    1. bool ExTreeProxy::insertRows(int position, int rows, const QModelIndex &parent)
    2. {
    3. ExObject *parentItem = parentItem = getItem(mapToSource(parent)); // here is the 2nd breakpoint
    4. ...
    5. }
    To copy to clipboard, switch view to plain text mode 



    and here how the function is called:

    Qt Code:
    1. QModelIndex index = mTree->selectionModel()->currentIndex(); // mTree is QTreeView
    2. int row;
    3. QModelIndex parent;
    4. if (!index.isValid()){
    5. row = 0;
    6. parent = QModelIndex();
    7. }
    8. else {
    9. row = index.row()+1;
    10. parent = index.parent();
    11. }
    12. mProxyModel->insertRows(row, 1, parent); // here is the 1st breakpoint
    To copy to clipboard, switch view to plain text mode 

    And I set 2 breakpoints
    - on line, where this function is called;
    - on the 1st line of this funcion (just in case - because I did not know what else to do - see later).
    Then I run application, make it stop on the 1st breakpoint and I press "Go into the function".
    And I immediatelly get an exception "Runtime Error! The application has requested the Runtime to terminate it in an unusual way... etc..."
    and then error in Qt Developer console:
    QSortFilterProxyModel: index from wrong model passed to mapToSource
    ASSERT: "!"QSortFilterProxyModel: index from wrong model passed to mapToSource"" in file itemmodels\qsortfilterproxymodel.cpp, line 380
    But I only entered the function - so mapToSource can not be called yet. So I can not even check the parent - if it is correct for mapping or not...
    And my breakpoint is on the first line of the function too... but it don't stop on the breakpoint too...

    There are lot's of such strange things with debugger... Sometimes it helps, but most of time it makes me desperate, that's all.
    Maybe because I am a newbie in Qt and C++. Maybe because there is really something wrong with it.
    Last edited by high_flyer; 10th September 2013 at 15:09. Reason: code tags

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    Why do you do:
    Qt Code:
    1. ExObject *parentItem = parentItem = ... // here is the 2nd breakpoint
    To copy to clipboard, switch view to plain text mode 
    ?
    Even though it is legal code, it suggests to me you are doing things wrong...

    Try clean rebuilding, that would be the first easy thing to do.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

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

    Default Re: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    What does getItem() do? What does the implementation of insertRows() in the model look like?
    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.


  6. #6
    Join Date
    Sep 2013
    Location
    Moscow
    Posts
    9
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    Quote Originally Posted by high_flyer View Post
    Why do you do:
    Qt Code:
    1. ExObject *parentItem = parentItem = ... // here is the 2nd breakpoint
    To copy to clipboard, switch view to plain text mode 
    ?
    Even though it is legal code, it suggests to me you are doing things wrong...

    Try clean rebuilding, that would be the first easy thing to do.
    Oh, I'm sorry, this line is a missprint, it is of course this:
    Qt Code:
    1. ExObject *parentItem = getItem(mapToSource(parent));
    To copy to clipboard, switch view to plain text mode 

    Tried to rebuild - no difference.


    Added after 4 minutes:


    Quote Originally Posted by wysota View Post
    What does getItem() do?
    Qt Code:
    1. ExObject *ExTreeProxy::getItem(const QModelIndex &index) const
    2. {
    3. if (index.isValid()) {
    4. ExObject *item = static_cast<ExObject*>(index.internalPointer());
    5. if (item)
    6. return item;
    7. }
    8. return (static_cast<ExTree*>(sourceModel()))->getItem(QModelIndex());
    9. }
    To copy to clipboard, switch view to plain text mode 

    ExObject here is a tree element. ExTree derived from QAbstractItemModel.

    Quote Originally Posted by wysota View Post
    What does the implementation of insertRows() in the model look like?
    Here is the complete insertRows():
    Qt Code:
    1. bool ExTreeProxy::insertRows(int position, int rows, const QModelIndex &parent)
    2. {
    3. ExObject *parentItem = getItem(mapToSource(parent));
    4. bool success;
    5.  
    6. beginInsertRows(parent, position, position + rows - 1);
    7. success = parentItem->insertChildren(position, rows, parentItem->columnCount());
    8. endInsertRows();
    9.  
    10. if(success) emit layoutChanged();
    11. return success;
    12. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by KanareykaVBusikah; 11th September 2013 at 08:37.

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

    Default Re: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    What if you check if parent is a valid index before passing it to mapToSource? What is the model of the index passed there, anyway?
    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.


  8. #8
    Join Date
    Sep 2013
    Location
    Moscow
    Posts
    9
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    Quote Originally Posted by wysota View Post
    What if you check if parent is a valid index before passing it to mapToSource?
    I will try, but don't see the point of it - parent is being defined just before insertRows() is called - you can see, how it is done, in comment #3.
    For me it looks fine, and debugger shows normal parent - when I breakpoint on "mProxyModel->insertRows(row, 1, parent)".

    Quote Originally Posted by wysota View Post
    What is the model of the index passed there, anyway?
    Sorry, I am not sure I understand fully what you mean.
    Could you explain? Or maybe the call in comment #3 will help? Getting parent and insertRows() call are shown there.
    It is taken from tree selection model - so, I think it is proxy model index. Am I wrong?

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

    Default Re: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    Quote Originally Posted by KanareykaVBusikah View Post
    I will try, but don't see the point of it - parent is being defined just before insertRows() is called - you can see, how it is done, in comment #3.
    And it can be an empty model index...

    Sorry, I am not sure I understand fully what you mean.
    What is the object returned from QModelIndex::model() for that index. Is it the proxy model instance or some other model.
    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.


  10. #10
    Join Date
    Sep 2013
    Location
    Moscow
    Posts
    9
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    Quote Originally Posted by wysota View Post
    And it can be an empty model index...
    It is not empty definitely, this I did have checked (debuger shows row index there and correct object data and so on).

    Quote Originally Posted by wysota View Post
    What is the object returned from QModelIndex::model() for that index. Is it the proxy model instance or some other model.
    Oh, thanks really! I did not grasp, I could check the model
    Will try.

  11. #11
    Join Date
    Sep 2013
    Location
    Moscow
    Posts
    9
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QTreeView + QAbstractItemModel + QSortFilterProxyModel = insertRows fails

    Hello again!
    Sorry for long absence - there just was some important and pressing issues to be done in my life.

    The idea of QModelIndex::model() helped me to understand some details, but I advanced only a little.
    Now I see something in gdb output, that I can not understand and explain - I expect different to see.
    I was sure I am experienced enough to understand, but no, what I see makes me completely desperate.

    I made a pair of screenshot, so I hope you can help me to explain what I see - and WHY I see it.
    These are screenshots of debugging insertRow.
    To run the function - I a) select an item in my tree and b) enter some text (pSubject variable). Then the function is called.

    qt1.jpg
    On this picture you see:
    - I stoped at "QModelIndex index = index from selection model"
    - Pressed "F10" to move to the next statement.
    Now I see the correct index variable: column = 0, row = 9, model = ExTreeProxy (that is proxy model).
    It is marked with red rectangles.
    So, it's everything ok on this sceen.

    Then come oddnesses:
    qt2.jpg

    Here you see
    1) mark "1" on the picture - shows what I get after statement "sourceIndex = map from index".
    As I selected index - I see it in the tree, I get it correctly from selection model - so, I expect to have correct sourceIndex.
    But I get invalid one.
    2) mark "2" on the picture - shows what I get when I go into "else" branch.
    There is an incorrect index (column=0, row=0). What is it? On what reason index changed?

    I thought this might be some errors in debugger - and I have build gdb from source.
    But this did not help. I see the same oddnesses again.

    Can you help in any way? Explain why I see this for the beginning...

Similar Threads

  1. Replies: 10
    Last Post: 22nd March 2019, 15:03
  2. QSortFilterProxyModel QAbstractItemModel
    By Qiieha in forum Qt Programming
    Replies: 2
    Last Post: 29th October 2012, 08:01
  3. QSortFilterProxyModel::insertRows always adds rows to the end
    By Agnostic Pope in forum Qt Programming
    Replies: 1
    Last Post: 7th May 2012, 23:23
  4. Replies: 2
    Last Post: 8th December 2010, 20:37
  5. Need help with QTreeView/QAbstractItemModel
    By Valheru in forum Qt Programming
    Replies: 5
    Last Post: 28th August 2006, 15:09

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
  •  
Qt is a trademark of The Qt Company.