Results 1 to 3 of 3

Thread: Subclassing QSortFilterProxyModel problem

  1. #1
    Join Date
    Mar 2010
    Posts
    7
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Subclassing QSortFilterProxyModel problem

    Hello!

    I've met a problem with subclassing QSortFilterProxyModel.
    What I want is a proxy model which hides some of the source table model columns (and also supports sorting, and do some other things).

    I subclass a QSortFilterProxyModel and override filterAcceptsColumn() function.

    The decision on which column to hide is based on rather huge computation. So I wish to do such computations only when source model changes significantly, e,g, when new column is added. Thus I connect source model's corresponding signal to my proxy's updateCache() slot. That slot does the computation and saves it's results in to a vector of bools.

    filterAcceptsColumn() function simply uses this vector to find out which column to hide.

    Below is a complete test code which I expect to work. But it crashes.

    The reason of the failure is that QSortFilterProxyModel() constructor also connects that signal to it's private slot. That slot is invoked before my updateCache() slot in a subclass. That parent slot emits similsr signal which is connected to a view object. The view tries to react on model change and calls columnCount() functoin of the proxy which in turn calls filterAcceptsColumn() for every column of a changed source model. But my updateCache() slot in a subclass was not called yet. Thus the required computation was not done for a new number of a source columns and the vector was not resized properly. The program crashes trying to access non existent element of the vector.

    Any suggestions on how to solve this problem?

    MyProxy.h
    Qt Code:
    1. #ifndef MYPROXY_H
    2. #define MYPROXY_H
    3.  
    4. #include <QSortFilterProxyModel>
    5. #include <QDebug>
    6. #include <QVector>
    7.  
    8. class MyProxy : public QSortFilterProxyModel
    9. {
    10. Q_OBJECT
    11. private:
    12. QVector<bool> hiddenColumns;
    13.  
    14. public:
    15. void setSourceModel(QAbstractItemModel* sourceModel)
    16. {
    17. QSortFilterProxyModel::setSourceModel(sourceModel);
    18.  
    19. updateCache();
    20.  
    21. connect(sourceModel, SIGNAL(columnsInserted(const QModelIndex&, int, int)),
    22. SLOT(updateCache()));
    23. }
    24.  
    25. virtual bool filterAcceptsColumn(int source_column, const QModelIndex&) const
    26. {
    27. qDebug() << "filterAcceptsColumn(): column = " << source_column <<
    28. "\tcached = " << hiddenColumns.size();
    29. return ! hiddenColumns.at(source_column);
    30. }
    31.  
    32. private slots:
    33. void updateCache()
    34. {
    35. qDebug() << "updateCache()";
    36.  
    37. hiddenColumns.resize(sourceModel()->columnCount());
    38.  
    39. for (int c = 0; c < hiddenColumns.size(); c++)
    40. hiddenColumns[c] = c % 2; // consider huge computation here
    41. }
    42.  
    43. };
    44.  
    45. #endif // MYPROXY_H
    To copy to clipboard, switch view to plain text mode 
    MyProxy.cpp
    Qt Code:
    1. #include "MyProxy.h"
    2.  
    3. #include <QApplication>
    4. #include <QTableView>
    5. #include <QStandardItemModel>
    6.  
    7. int main(int argc, char *argv[])
    8. {
    9. QApplication a(argc, argv);
    10.  
    11. QStandardItemModel source(1, 1);
    12. MyProxy proxy;
    13. proxy.setSourceModel(& source);
    14.  
    15. v.setModel(& source);
    16. v.show();
    17.  
    18. qDebug() << "adding column...";
    19. source.setColumnCount(2);
    20.  
    21. return a.exec();
    22. }
    To copy to clipboard, switch view to plain text mode 
    Program output:
    updateCache()
    adding column...
    filterAcceptsColumn(): column = 0 cached = 1
    filterAcceptsColumn(): column = 1 cached = 1
    ASSERT failure in QVector<T>::at: "index out of range", file ..\..\..\..\Qt\2010.05\qt\include/QtCore/../../src/corelib/tools/qvector.h, line 339
    Invalid parameter passed to C runtime function.
    Invalid parameter passed to C runtime function.
    P.S. I use Qt 4.7 on Windows with gcc

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

    Default Re: Subclassing QSortFilterProxyModel problem

    One idea would be to connecto to columnsAboutToBeInserted. Another would be to perform the computations in filterAcceptsColumn() after detecting that the column count has changed.
    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
    Mar 2010
    Posts
    7
    Thanks
    5
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Subclassing QSortFilterProxyModel problem

    Thanks for your answer. However...
    Quote Originally Posted by wysota View Post
    One idea would be to connecto to columnsAboutToBeInserted.
    I need the new (inserted, changed) data for the computation. On the "...AboutToBe..." stage the new data is not available.
    Quote Originally Posted by wysota View Post
    Another would be to perform the computations in filterAcceptsColumn() after detecting that the column count has changed.
    This should work with column addition (and removal). However my proxy have to react on other events as well, such as (headerDataChanged, layoutChanged, modelReset). I omitted them in the example code for simplicity.

Similar Threads

  1. Replies: 1
    Last Post: 9th August 2009, 19:51
  2. Problem QSortFilterProxyModel
    By estanisgeyer in forum Qt Programming
    Replies: 3
    Last Post: 15th June 2009, 18:51
  3. Problem with QTreeWidget after subclassing
    By steve918 in forum Qt Programming
    Replies: 2
    Last Post: 28th July 2006, 18:51
  4. QSortFilterProxyModel problem
    By blukske in forum Qt Programming
    Replies: 8
    Last Post: 22nd June 2006, 08:26
  5. Subclassing QSortFilterProxyModel
    By r366y in forum Qt Programming
    Replies: 2
    Last Post: 14th June 2006, 15:26

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.