Results 1 to 11 of 11

Thread: Chained QSortFilterProxyModels lead to crashes on modelReset

  1. #1
    Join Date
    Feb 2006
    Posts
    32
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Chained QSortFilterProxyModels lead to crashes on modelReset

    I have a TreeItemModel visualised by a View, which uses some custom SortFilterProxyModels (i.e. classes derived from QSortFilterProxyModel) chained together. Those classes are performing different types of filtering. As long as I am emitting only dataChanged() events from the ItemModel everything works fine.

    However, as soon as I emit a modelReset() from the ItemModel, the application crashes with a backtrace I don't get any clues from. I've played around a little, and it seems that using more than one SortFilter model leads to a crash (i.e. chaining two SortFilter models in a row). If I restrict myself to one model, things seem to work out.

    The backtraces of a crash vary depending on the conditions.
    Here are two versions (all orginating in calling reset() from the ItemModel).
    Qt Code:
    1. #0 0x00002b61a15c213f in QSortFilterProxyModel::index () from /usr/lib/libQtGui.so.4
    2. #1 0x00002b61a15c23a7 in QSortFilterProxyModel::parent () from /usr/lib/libQtGui.so.4
    3. #2 0x00002b61a15c2142 in QSortFilterProxyModel::index () from /usr/lib/libQtGui.so.4
    4. #3 0x00002b61a15c23a7 in QSortFilterProxyModel::parent () from /usr/lib/libQtGui.so.4
    5. #4 0x00002b61a19871cb in QPersistentModelIndex::parent () from /usr/lib/libQtCore.so.4
    6. #5 0x00002b61a1594ee4 in QItemSelectionRange::indexes () from /usr/lib/libQtGui.so.4
    7. #6 0x00002b61a1594ffe in QItemSelection::indexes () from /usr/lib/libQtGui.so.4
    8. #7 0x00002b61a159510c in QItemSelection::indexes () from /usr/lib/libQtGui.so.4
    9. #8 0x00002b61a1599e5f in QItemSelectionModel::qt_metacall () from /usr/lib/libQtGui.so.4
    10. #9 0x00002b61a199f4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    11. #10 0x00002b61a15c52d1 in QSortFilterProxyModel::~QSortFilterProxyModel () from /usr/lib/libQtGui.so.4
    12. #11 0x00002b61a15c5634 in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    13. #12 0x00002b61a199f4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    14. #13 0x00002b61a15c5590 in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    15. #14 0x00002b61a5bd78e3 in NTagModel::FilterSelectedProxyModel::qt_metacall (this=0xde18d8,
    16. _c=QMetaObject::InvokeMetaMethod, _id=23, _a=0x7fff0a86cc70)
    17. at .moc/moc_filterselectedproxymodel.cpp:56
    18. #15 0x00002b61a199f4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    19. #16 0x00002b61a15c554b in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    20. #17 0x00002b61a5bd78e3 in NTagModel::FilterSelectedProxyModel::qt_metacall (this=0xde18d8,
    21. _c=QMetaObject::InvokeMetaMethod, _id=26, _a=0x7fff0a86d1e0)
    22. at .moc/moc_filterselectedproxymodel.cpp:56
    23. #18 0x00002b61a199f4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    24. #19 0x00002b61a5bc4ca6 in NTagModel::VocabularyModel::setData (this=0x6c7b30, index=@0x7fff0a86d2d0,
    25. value=@0x7fff0a86d390, role=32) at vocabularymodel.cpp:238
    26. #20 0x00002b61a15c0519 in QSortFilterProxyModel::setData () from /usr/lib/libQtGui.so.4
    27. #21 0x00002b61a15c0519 in QSortFilterProxyModel::setData () from /usr/lib/libQtGui.so.4
    28. #22 0x00002b61a5bd0f5a in NTagModel::UnselectedTagsView::onItemDoubleClicked (this=0xde18b0,
    29. index=@0xe6e050) at unselectedtagsview.cpp:109
    30. #23 0x00002b61a5bd7817 in NTagModel::UnselectedTagsView::qt_metacall (this=0xde18b0,
    31. _c=QMetaObject::InvokeMetaMethod, _id=1, _a=0x7fff0a86d8f0) at .moc/moc_unselectedtagsview.cpp:67
    32. #24 0x00002b61a199f4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    33. #25 0x00002b61a1557345 in QAbstractItemView::doubleClicked () from /usr/lib/libQtGui.so.4
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #0 0x00002b414655c013 in QAbstractProxyModel::mapSelectionFromSource () from /usr/lib/libQtGui.so.4
    2. #1 0x00002b414655df40 in QSortFilterProxyModel::rowCount () from /usr/lib/libQtGui.so.4
    3. #2 0x00002b414655d740 in QSortFilterProxyModel::lessThan () from /usr/lib/libQtGui.so.4
    4. #3 0x00002b414655e14d in QSortFilterProxyModel::index () from /usr/lib/libQtGui.so.4
    5. #4 0x00002b414655e3a7 in QSortFilterProxyModel::parent () from /usr/lib/libQtGui.so.4
    6. #5 0x00002b4146532a54 in QItemSelectionModel::isRowSelected () from /usr/lib/libQtGui.so.4
    7. #6 0x00002b41465330c7 in QItemSelectionModel::isRowSelected () from /usr/lib/libQtGui.so.4
    8. #7 0x00002b4146535e53 in QItemSelectionModel::qt_metacall () from /usr/lib/libQtGui.so.4
    9. #8 0x00002b414693b4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    10. #9 0x00002b4146561366 in QSortFilterProxyModel::~QSortFilterProxyModel () from /usr/lib/libQtGui.so.4
    11. #10 0x00002b4146561634 in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    12. #11 0x00002b414693b4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    13. #12 0x00002b4146561383 in QSortFilterProxyModel::~QSortFilterProxyModel () from /usr/lib/libQtGui.so.4
    14. #13 0x00002b4146561634 in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    15. #14 0x00002b414ab73983 in NTagModel::FilterSelectedProxyModel::qt_metacall (this=0xddcb48,
    16. _c=QMetaObject::InvokeMetaMethod, _id=28, _a=0x7fff658d2100)
    17. at .moc/moc_filterselectedproxymodel.cpp:56
    18. #15 0x00002b414693b4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    19. #16 0x00002b4146561383 in QSortFilterProxyModel::~QSortFilterProxyModel () from /usr/lib/libQtGui.so.4
    20. #17 0x00002b4146561634 in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    21. #18 0x00002b414ab7672f in NTagModel::EmptyTagFilter::qt_metacall (this=0xde1ab0,
    22. _c=QMetaObject::InvokeMetaMethod, _id=28, _a=0x7fff658d26c0) at .moc/moc_emptytagfilter.cpp:56
    23. #19 0x00002b414693b4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    24. #20 0x00002b4146561590 in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    25. #21 0x00002b414ab73a5b in NTagModel::FilterHiddenProxyModel::qt_metacall (this=0xddcb60,
    26. _c=QMetaObject::InvokeMetaMethod, _id=23, _a=0x7fff658d2c30)
    27. at .moc/moc_filterhiddenproxymodel.cpp:56
    28. #22 0x00002b414693b4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    29. #23 0x00002b414656154b in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    30. #24 0x00002b414ab73a5b in NTagModel::FilterHiddenProxyModel::qt_metacall (this=0xddcb60,
    31. _c=QMetaObject::InvokeMetaMethod, _id=26, _a=0x7fff658d31a0)
    32. at .moc/moc_filterhiddenproxymodel.cpp:56
    33. #25 0x00002b414693b4cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    34. #26 0x00002b414ab60ca6 in NTagModel::VocabularyModel::setData (this=0x632270, index=@0x7fff658d3290,
    35. value=@0x7fff658d33f0, role=32) at vocabularymodel.cpp:238
    36. #27 0x00002b414655c519 in QSortFilterProxyModel::setData () from /usr/lib/libQtGui.so.4
    37. #28 0x00002b414655c519 in QSortFilterProxyModel::setData () from /usr/lib/libQtGui.so.4
    38. #29 0x00002b414655c519 in QSortFilterProxyModel::setData () from /usr/lib/libQtGui.so.4
    39. #30 0x00002b414655c519 in QSortFilterProxyModel::setData () from /usr/lib/libQtGui.so.4
    40. #31 0x00002b414ab6cf5a in NTagModel::UnselectedTagsView::onItemDoubleClicked (this=0xddcb20,
    41. index=@0x137ce20) at unselectedtagsview.cpp:109
    To copy to clipboard, switch view to plain text mode 


    I have no small test application, but if you use Debian you can get the source from
    svn co https://packagesearch.svn.sourceforge.net/svnroot/packagesearch/branches/2.2-removeQT3 packagesearch
    and download the build-depends using "apt-get build-dep packagesearch".
    The relevant code is located in src/plugins/debtagsplugin/unselectedtagsview.cpp
    The crashes happen if you double click on some items of the top right list.

    There the lines
    Qt Code:
    1. _filterChain.push_back(&_hiddenFilterProxyModel);
    2. _filterChain.push_back(_pTagFilter);
    3. _filterChain.push_back(&_filterSelectedProxyModel);
    4. _filterChain.push_back(_pTextFilter);
    To copy to clipboard, switch view to plain text mode 
    control which filters shall be switched on. If you are willing to investigate and need more information please ask.

    I am totally out of ideas, so any help would be appreciated.

    Regards Ben

  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: Chained QSortFilterProxyModels lead to crashes on modelReset

    We would surely like to see a code snippet that handles the situation where the crash occurs (the slot with index 23 from FilterSelectedProxyModel or whatever that is. Why is the destructor of a proxy model called? This shouldn't happen inside a slot.

  3. #3
    Join Date
    Feb 2006
    Posts
    32
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Chained QSortFilterProxyModels lead to crashes on modelReset

    We would surely like to see a code snippet that handles the situation where the crash occurs (the slot with index 23 from FilterSelectedProxyModel or whatever that is.
    You are probably referring to the line
    Qt Code:
    1. #14 0x00002b61a5bd78e3 in NTagModel::FilterSelectedProxyModel::qt_metacall (this=0xde18d8,
    2. _c=QMetaObject::InvokeMetaMethod, _id=23, _a=0x7fff0a86cc70)
    3. at .moc/moc_filterselectedproxymodel.cpp:56
    To copy to clipboard, switch view to plain text mode 

    I have no idea about the slot that is called in FitlerSelectedProxyModel.
    If there were a slot to be called, shouldn't it appear in the backtrace?
    I don't know to which slot the id refers.

    Also I have no idea, why the destructor of the QSortFilterProxyModel is called. I thought it is something that happens internally in the QSortFilterProxyModel. The only method I override in my custom filters is the constructor and the filterAcceptsRow() method.

  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: Chained QSortFilterProxyModels lead to crashes on modelReset

    At the bottom of the stack there is your model, which might be influencing the proxies. The backtrace doesn't seem complete and they end at two completely different methods, so it's hard to say what's wrong just by looking at this trace. Do you reset a model on doubleclicking one of its items? If so, I don't think you should do that.

    Please show the code of your proxy and tell us which signals from the views you connected to which slots (i.e. what do they do).

  5. #5
    Join Date
    Feb 2006
    Posts
    32
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Chained QSortFilterProxyModels lead to crashes on modelReset

    The only connection I am setting up is connecting the doubleClicked(QModelIndex) signal of the view to the onItemDoubleClicked(const QModelIndex&) slot in the view.
    From onItemDoubleClicked() I am calling "model()->setData(index, true, SelectedRole)".

    The remaining part is setting the filters like this:
    Qt Code:
    1. view->setModel(filter1);
    2. filter1->setSourceModel(filter2);
    3. filter2->setSourceModel(model);
    To copy to clipboard, switch view to plain text mode 
    No additional connections are made.

    I will add the code for the proxies in a separate post.
    The backtraces vary a bit depending on the SortFilterProxyModels I am using. For simplicity for the remaining analysis I am restricting things to only two filters (FilterSelctedProxyModel and TreeSortFilter).
    The full backtrace one gets when using those two filters is:

    Qt Code:
    1. #0 0x00002b8586d43139 in QSortFilterProxyModel::index () from /usr/lib/libQtGui.so.4
    2. #1 0x00002b8586d433a7 in QSortFilterProxyModel::parent () from /usr/lib/libQtGui.so.4
    3. #2 0x00002b8586d17a54 in QItemSelectionModel::isRowSelected () from /usr/lib/libQtGui.so.4
    4. #3 0x00002b8586d180c7 in QItemSelectionModel::isRowSelected () from /usr/lib/libQtGui.so.4
    5. #4 0x00002b8586d1ae53 in QItemSelectionModel::qt_metacall () from /usr/lib/libQtGui.so.4
    6. #5 0x00002b85871204cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    7. #6 0x00002b8586d46366 in QSortFilterProxyModel::~QSortFilterProxyModel () from /usr/lib/libQtGui.so.4
    8. #7 0x00002b8586d46634 in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    9. #8 0x00002b85871204cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    10. #9 0x00002b8586d46590 in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    11. #10 0x00002b858b3588e3 in NTagModel::FilterSelectedProxyModel::qt_metacall (this=0xdf16c8, _c=QMetaObject::InvokeMetaMethod, _id=23,
    12. _a=0x7fff250ed4f0) at .moc/moc_filterselectedproxymodel.cpp:56
    13. #11 0x00002b85871204cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    14. #12 0x00002b8586d4654b in QSortFilterProxyModel::qt_metacall () from /usr/lib/libQtGui.so.4
    15. #13 0x00002b858b3588e3 in NTagModel::FilterSelectedProxyModel::qt_metacall (this=0xdf16c8, _c=QMetaObject::InvokeMetaMethod, _id=26,
    16. _a=0x7fff250eda60) at .moc/moc_filterselectedproxymodel.cpp:56
    17. #14 0x00002b85871204cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    18. #15 0x00002b858b345ca6 in NTagModel::VocabularyModel::setData (this=0x6f64f0, index=@0x7fff250edb50, value=@0x7fff250edc10, role=32)
    19. at vocabularymodel.cpp:238
    20. #16 0x00002b8586d41519 in QSortFilterProxyModel::setData () from /usr/lib/libQtGui.so.4
    21. #17 0x00002b8586d41519 in QSortFilterProxyModel::setData () from /usr/lib/libQtGui.so.4
    22. #18 0x00002b858b351f5a in NTagModel::UnselectedTagsView::onItemDoubleClicked (this=0xdf16a0, index=@0x13f9e50)
    23. at unselectedtagsview.cpp:109
    24. #19 0x00002b858b358817 in NTagModel::UnselectedTagsView::qt_metacall (this=0xdf16a0, _c=QMetaObject::InvokeMetaMethod, _id=1,
    25. _a=0x7fff250ee170) at .moc/moc_unselectedtagsview.cpp:67
    26. #20 0x00002b85871204cb in QMetaObject::activate () from /usr/lib/libQtCore.so.4
    27. #21 0x00002b8586cd8345 in QAbstractItemView::doubleClicked () from /usr/lib/libQtGui.so.4
    28. #22 0x00002b8586d092c5 in QTreeView::mouseDoubleClickEvent () from /usr/lib/libQtGui.so.4
    29. #23 0x00002b85869d4575 in QWidget::event () from /usr/lib/libQtGui.so.4
    30. #24 0x00002b8586c20cd9 in QFrame::event () from /usr/lib/libQtGui.so.4
    31. #25 0x00002b8586c883da in QAbstractScrollArea::viewportEvent () from /usr/lib/libQtGui.so.4
    32. #26 0x00002b8586cdb4cb in QAbstractItemView::viewportEvent () from /usr/lib/libQtGui.so.4
    33. #27 0x00002b8586c89708 in QAbstractScrollArea::setViewport () from /usr/lib/libQtGui.so.4
    34. #28 0x00002b8586991ce2 in QApplicationPrivate::notify_helper () from /usr/lib/libQtGui.so.4
    35. #29 0x00002b8586994291 in QApplication::notify () from /usr/lib/libQtGui.so.4
    36. #30 0x00002b85869e4e21 in QApplication::x11ProcessEvent () from /usr/lib/libQtGui.so.4
    37. #31 0x00002b85869e3cff in QApplication::x11ProcessEvent () from /usr/lib/libQtGui.so.4
    38. #32 0x00002b8586a05773 in QX11Info::copyX11Data () from /usr/lib/libQtGui.so.4
    39. #33 0x00002b8588c58913 in g_main_context_dispatch () from /usr/lib/libglib-2.0.so.0
    40. #34 0x00002b8588c5b75d in g_main_context_check () from /usr/lib/libglib-2.0.so.0
    41. #35 0x00002b8588c5bc7e in g_main_context_iteration () from /usr/lib/libglib-2.0.so.0
    42. #36 0x00002b85871309a2 in QEventDispatcherGlib::processEvents () from /usr/lib/libQtCore.so.4
    43. #37 0x00002b8586a0558f in QX11Info::copyX11Data () from /usr/lib/libQtGui.so.4
    44. #38 0x00002b858710f738 in QEventLoop::processEvents () from /usr/lib/libQtCore.so.4
    45. #39 0x00002b858710f849 in QEventLoop::exec () from /usr/lib/libQtCore.so.4
    46. #40 0x00002b85871119ce in QCoreApplication::exec () from /usr/lib/libQtCore.so.4
    47. #41 0x000000000044b638 in main (argc=1, argv=0x7fff250efa18) at main.cpp:117
    To copy to clipboard, switch view to plain text mode 

    If the source file can be of help, you can view them here: http://packagesearch.svn.sourceforge...debtagsplugin/

    The model is vocabularymodel.*
    The view is unselectedtagsview.*
    The filters are unselectedtagsview.cpp (TreeSortFilter) and filterselectedproxymodel.*.

  6. #6
    Join Date
    Feb 2006
    Posts
    32
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Chained QSortFilterProxyModels lead to crashes on modelReset

    The FilterSelectedProxyModel has the filterAcceptsRow() method:

    Qt Code:
    1. bool FilterSelectedProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
    2. {
    3. QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
    4. if (sourceModel()->data(index, TypeRole).toInt() == FacetTypeItem)
    5. return true;
    6. bool isSelected = sourceModel()->data(index, SelectedRole).toBool();
    7. return isSelected == _includeSelected;
    8. }
    To copy to clipboard, switch view to plain text mode 

    The full definition of the TreeSortFilter class is:
    Qt Code:
    1. class TreeSortFilter : public QSortFilterProxyModel
    2. {
    3. public:
    4. TreeSortFilter(QObject * pParent = 0) : QSortFilterProxyModel(pParent)
    5. {}
    6. virtual bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
    7. {
    8. QModelIndex current = sourceModel()->index(sourceRow, filterKeyColumn(), sourceParent);
    9. for( int i = 0; i < sourceModel()->rowCount(current); ++i )
    10. {
    11. const QModelIndex child = current.child(i, current.column());
    12. if (filterAcceptsRow(i, current))
    13. return true;
    14. }
    15. return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
    16. }
    17. };
    To copy to clipboard, switch view to plain text mode 

    The code in the model's setData method (which calls the reset) looks like this:
    Qt Code:
    1. case SelectedRole:
    2. {
    3. ItemData* pData = (ItemData*) index.internalPointer();
    4. TagData* pTagData = pData->toTagData();
    5. if (!pTagData)
    6. return false;
    7. pTagData->selected = value.toBool();
    8. if (value.toBool()) // the tag is selected
    9. _selectedTags.insert(pTagData->tag);
    10. else // the tag is unselected
    11. _selectedTags.erase(pTagData->tag);
    12. reset();
    13. return true;
    14. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by bmesing; 26th April 2007 at 19:26. Reason: added code snippet from setData() method

  7. #7
    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: Chained QSortFilterProxyModels lead to crashes on modelReset

    Add some checks into setData():
    - check if index.isValid()
    - check if the internal pointer is correct

    and finally
    - don't call reset() inside setData - what sense does it make to do that? You should emit dataChanged(index) here, not reset the model...

    After you do that see if the problem persists as I expect it's calling reset() from setData() that causes the error (it's possible that the proxies get confused). Why do you want to reset the model here anyway?

  8. #8
    Join Date
    Oct 2006
    Posts
    279
    Thanks
    6
    Thanked 40 Times in 39 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Chained QSortFilterProxyModels lead to crashes on modelReset

    I only want to add that I've found ModelTest extremely useful. I love the model/view way of doing things, but implementing a tree model with different proxies/filters is pretty tricky business. ModelTest quickly finds the most common pitfalls for you.

  9. The following user says thank you to spud for this useful post:

    bmesing (1st May 2007)

  10. #9
    Join Date
    Feb 2006
    Posts
    32
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: Chained QSortFilterProxyModels lead to crashes on modelReset

    I have added ModelTest for Testing my core model (which detected some bugs in my model). However, the described problem still persists. I have also added ModelTest to every single Filter model, with no problems being detected.

    The reason for calling reset() inside setData() is, that one of the filters needs to re-filter every item after a single item changes inside the model (since the filter itself is depends on the model). I wanted to accomplish this behaviour by calling reset().

    The correct way would be to connect the SortFilterModel to the dataChanged signal of the Core model and call filterChanged() in response. However, this did also lead to a crash in the progrem, and I suspected it might be due to calling filterChanged() from an event handler of dataChanged(). Therefore I tried calling reset from inside setData().

    You argue that calling reset from setData() might be the source of the problem, and I agree. I have tried an alternative: emitting data changed for every single element in the model in response to setData() and it works (though it is inacceptably slow). However, I fail to see, why reset() should lead to the crash. I always thought it is just a shortcut for emitting dataChanged for all (or most) elements.

    When trying out using filterChanged() instead of calling reset() again, the ModelTest did detect a potential error.
    The error is detected in one of the model filters: When calling data() with an index with a row value that is (seems to be) larger than the row count the filter forwards the call to the next filter with row and col = -1. This returns an invalid QVariant which is detected as a potential error.
    I am not quite sure, why data() is called with an index larger than row count.

    I appreciate your help!

  11. #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: Chained QSortFilterProxyModels lead to crashes on modelReset

    Quote Originally Posted by bmesing View Post
    The correct way would be to connect the SortFilterModel to the dataChanged signal of the Core model and call filterChanged() in response. However, this did also lead to a crash in the progrem, and I suspected it might be due to calling filterChanged() from an event handler of dataChanged(). Therefore I tried calling reset from inside setData().
    filterChanged() should have worked.

    However, I fail to see, why reset() should lead to the crash.
    Possibly because you destroy some internal model structures which might still be in use.

    I always thought it is just a shortcut for emitting dataChanged for all (or most) elements.
    No, it's not. The whole model is reinitialized from scratch.

    I am not quite sure, why data() is called with an index larger than row count.
    Because a stale index might still be in use, especially if you reset the model as a result of a signal emitting an index that is no longer valid after reset.

  12. #11
    Join Date
    Feb 2006
    Posts
    32
    Thanks
    3
    Thanked 1 Time in 1 Post
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Smile Re: Chained QSortFilterProxyModels lead to crashes on modelReset

    Ok, I've given this topic some month of rest, and it seems that with a recent QT version (4.3.1) everything works out fine. It seems this was a bug in QT after all...

    Regards Ben

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.