Results 1 to 20 of 23

Thread: rowCount() is calling for all the top level items

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Jun 2015
    Location
    India
    Posts
    185
    Thanks
    8
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default rowCount() is calling for all the top level items

    I have customized QAbstractItemModel & QTreeView.

    rowCount() is calling for all the top level items in a view, is it a default behavior of model ? //I set setAllColumnsShowFocus( true ); setUniformRowHeights( true );
    If so, can we change this so that it will get called only for currently viewing items in view.

    I am dealing with huge data (millions of rows) because of this behavior there is some delay in viewing items.

    Any suggestions ?
    Thanks :-)

  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: rowCount() is calling for all the top level items

    Quote Originally Posted by prasad_N View Post
    rowCount() is calling for all the top level items in a view, is it a default behavior of model ?
    No, it's a default behaviour of QTreeView since the tree wants to know whether each of the items has child items.

    If so, can we change this so that it will get called only for currently viewing items in view.
    Hmm... I don't think the view cares about items that are not visible unless you asked items to be expanded, in which case it needs to calculate the total size of the tree for the scrollbar.
    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
    Jun 2015
    Location
    India
    Posts
    185
    Thanks
    8
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: rowCount() is calling for all the top level items

    Quote Originally Posted by wysota View Post
    Hmm... I don't think the view cares about items that are not visible unless you asked items to be expanded, in which case it needs to calculate the total size of the tree for the scrollbar.
    you mean we can change this default behavior right ?
    If yes, How can we do this.
    Thanks :-)

  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: rowCount() is calling for all the top level items

    This example shows that the view does not query the whole model when it initializes:

    Qt Code:
    1. #include <QtWidgets>
    2.  
    3.  
    4. class Model : public QAbstractListModel {
    5. public:
    6. Model(QObject *parent = 0) : QAbstractListModel(parent) {}
    7.  
    8. int rowCount(const QModelIndex &parent = QModelIndex()) const {
    9. qDebug() << Q_FUNC_INFO << parent;
    10. if(parent.isValid()) return 0;
    11. return 1000;
    12. }
    13. QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const {
    14. if(parent.isValid()) return QModelIndex();
    15. return createIndex(row, column, (void*)0);
    16. }
    17.  
    18. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
    19. if(role == Qt::DisplayRole) return index.row()+1;
    20. return QVariant();
    21. }
    22. };
    23.  
    24. int main(int argc, char **argv) {
    25. QApplication app(argc, argv);
    26. Model model;
    27. v.setModel(&model);
    28. v.show();
    29. return app.exec();
    30. }
    To copy to clipboard, switch view to plain text mode 
    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
    Jun 2015
    Location
    India
    Posts
    185
    Thanks
    8
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: rowCount() is calling for all the top level items

    Quote Originally Posted by wysota View Post
    This example shows that the view does not query the whole model when it initializes:
    Quote Originally Posted by wysota View Post
    No, it's a default behaviour of QTreeView since the tree wants to know whether each of the items has child items:
    these 2 statements are conflicting right ?

    1. In my model rowCount is calling for all the top level items.

    my model is :

    Qt Code:
    1. QModelIndex TreeModel::index( int row, int column, const QModelIndex &parent ) const
    2. {
    3. if ( ! hasIndex(row, column, parent) )
    4. return QModelIndex();
    5.  
    6. TreeItem *parentItem;
    7.  
    8. if ( ! parent.isValid() )
    9. parentItem = m_rootItem;
    10. else
    11. parentItem = static_cast<TreeItem*>( parent.internalPointer() );
    12.  
    13. TreeItem *childItem = parentItem->child( row );
    14. if ( childItem )
    15. return createIndex( row, column, childItem );
    16. else
    17. return QModelIndex();
    18. }
    19.  
    20. QModelIndex TreeModel::parent( const QModelIndex &index ) const
    21. {
    22. if ( ! index.isValid() )
    23. return QModelIndex();
    24.  
    25. TreeItem *childItem = static_cast<TreeItem*>( index.internalPointer() );
    26. TreeItem *parentItem = childItem->parent();
    27.  
    28. if ( (parentItem == m_rootItem) || (parentItem == NULL))
    29. return QModelIndex();
    30.  
    31. return createIndex( parentItem->row(), 0, parentItem );
    32. }
    33.  
    34. int TreeModel::rowCount( const QModelIndex &parent ) const
    35. {
    36. if ( parent.column() > 0 )
    37. return 0;
    38.  
    39. TreeItem *parentItem;
    40. if ( ! parent.isValid() )
    41. parentItem = m_rootItem;
    42. else
    43. parentItem = static_cast<TreeItem*>( parent.internalPointer() );
    44.  
    45. return parentItem->childCount();
    46. }
    To copy to clipboard, switch view to plain text mode 


    2. When I change your model little bit on order to check tree function calling. in the index if(parent.isValid()) is not at all executing.

    Qt Code:
    1. int rowCount(const QModelIndex &parent = QModelIndex()) const {
    2. qDebug() << Q_FUNC_INFO << parent;
    3. if(parent.isValid()) return 2; //each parent with 2 child
    4. return 10; // 10 top most parrents
    5. }
    6.  
    7. QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const {
    8. if(parent.isValid()){ // this condition is not at all executing
    9. qDebug() << "Yes isValid = " << parent.child(row, column);
    10. return createIndex(row, column, (void*)parent.child(row, column).internalPointer()); //create &return child index
    11. }
    12.  
    13. return createIndex(row, column, (void*)0); // return top most elements index's
    14. }
    To copy to clipboard, switch view to plain text mode 


    What wrong am I doing here ?

    I don't want to use treeItems in my model for tree(if possible, I think it is possible with above implementation).
    Last edited by prasad_N; 8th July 2015 at 19:35.
    Thanks :-)

  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: rowCount() is calling for all the top level items

    Quote Originally Posted by prasad_N View Post
    these 2 statements are conflicting right ?
    Yes, I didn't express myself clearly. I meant that it is the view which is causing what you see, not the model. I didn't mean to say that "the view has to query all the indexes".

    1. In my model rowCount is calling for all the top level items.

    my model is :

    Qt Code:
    1. QModelIndex TreeModel::index( int row, int column, const QModelIndex &parent ) const
    2. {
    3. if ( ! hasIndex(row, column, parent) )
    4. return QModelIndex();
    5.  
    6. TreeItem *parentItem;
    7.  
    8. if ( ! parent.isValid() )
    9. parentItem = m_rootItem;
    10. else
    11. parentItem = static_cast<TreeItem*>( parent.internalPointer() );
    12.  
    13. TreeItem *childItem = parentItem->child( row );
    14. if ( childItem )
    15. return createIndex( row, column, childItem );
    16. else
    17. return QModelIndex();
    18. }
    19.  
    20. QModelIndex TreeModel::parent( const QModelIndex &index ) const
    21. {
    22. if ( ! index.isValid() )
    23. return QModelIndex();
    24.  
    25. TreeItem *childItem = static_cast<TreeItem*>( index.internalPointer() );
    26. TreeItem *parentItem = childItem->parent();
    27.  
    28. if ( (parentItem == m_rootItem) || (parentItem == NULL))
    29. return QModelIndex();
    30.  
    31. return createIndex( parentItem->row(), 0, parentItem );
    32. }
    33.  
    34. int TreeModel::rowCount( const QModelIndex &parent ) const
    35. {
    36. if ( parent.column() > 0 )
    37. return 0;
    38.  
    39. TreeItem *parentItem;
    40. if ( ! parent.isValid() )
    41. parentItem = m_rootItem;
    42. else
    43. parentItem = static_cast<TreeItem*>( parent.internalPointer() );
    44.  
    45. return parentItem->childCount();
    46. }
    To copy to clipboard, switch view to plain text mode 
    This is the implementation of QAbstractItemModel::hasIndex():
    Qt Code:
    1. bool QAbstractItemModel::hasIndex(int row, int column, const QModelIndex &parent) const
    2. {
    3. if (row < 0 || column < 0)
    4. return false;
    5. return row < rowCount(parent) && column < columnCount(parent);
    6. }
    To copy to clipboard, switch view to plain text mode 

    Therefore each time you call you index() implementation, it calls hasIndex() which in turn calls rowCount() for the parent. Possibly this applies to other methods and their default implementations.

    2. When I change your model little bit on order to check tree function calling. in the index if(parent.isValid()) is not at all executing.

    Qt Code:
    1. int rowCount(const QModelIndex &parent = QModelIndex()) const {
    2. qDebug() << Q_FUNC_INFO << parent;
    3. if(parent.isValid()) return 2; //each parent with 2 child
    4. return 10; // 10 top most parrents
    5. }
    6.  
    7. QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const {
    8. if(parent.isValid()){ // this condition is not at all executing
    9. qDebug() << "Yes isValid = " << parent.child(row, column);
    10. return createIndex(row, column, (void*)parent.child(row, column).internalPointer()); //create &return child index
    11. }
    12.  
    13. return createIndex(row, column, (void*)0); // return top most elements index's
    14. }
    To copy to clipboard, switch view to plain text mode 


    What wrong am I doing here ?
    Most likely you didn't change the base class to QAbstractItemModel. Apparently QTreeView has an optimization to not check child nodes for flat models.

    Qt Code:
    1. #include <QtWidgets>
    2.  
    3. #define BASEMODEL QAbstractItemModel
    4.  
    5. class Model : public BASEMODEL {
    6. public:
    7. Model(QObject *parent = 0) : BASEMODEL(parent) {}
    8.  
    9. int columnCount(const QModelIndex &parent = QModelIndex()) const { return 1; }
    10.  
    11. int rowCount(const QModelIndex &parent = QModelIndex()) const {
    12. qDebug() << Q_FUNC_INFO << parent;
    13. if(!parent.isValid()) return 10;
    14. if(parent.isValid() && !parent.parent().isValid()) return 2; // limit to two levels
    15.  
    16. return 0;
    17. }
    18. QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const {
    19. qDebug() << Q_FUNC_INFO << row << column << parent;
    20. if(parent.isValid()) {
    21. qDebug() << Q_FUNC_INFO << "parent valid";
    22. // we only need id of the parent since it identifies the item
    23. return createIndex(row, column, parent.row());
    24. }
    25. return createIndex(row, column, -1); // top level item has invalid parent
    26. }
    27.  
    28. QModelIndex parent(const QModelIndex &ind) const {
    29. qDebug() << Q_FUNC_INFO << ind;
    30. if(!ind.isValid()) return QModelIndex();
    31. int id = ind.internalId();
    32. if( id == -1) return QModelIndex();
    33. return index(id, 0); // return top-level item
    34. }
    35.  
    36. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const {
    37. if(role == Qt::DisplayRole) return index.row()+1;
    38. return QVariant();
    39. }
    40. };
    41.  
    42. int main(int argc, char **argv) {
    43. QApplication app(argc, argv);
    44. Model model;
    45. v.setModel(&model);
    46. v.show();
    47. return app.exec();
    48. }
    To copy to clipboard, switch view to plain text mode 

    I don't want to use treeItems in my model for tree(if possible, I think it is possible with above implementation).
    Then don't use them

    By the way, changing the base class to QAbstractItemModel does cause the tree view to query rowCount for all the top-level items at start, I will try to see why this happens. You can probably switch some property and it will stop doing that.

    Edit: It looks like during layout of the tree, the widget calls rowCount() on items that have children. What is worrying is that it also calls canFetchMore() && fetchMore() for them which in my opinion defeats the purpose of implementing those two methods at all at least for two level models.
    Last edited by wysota; 8th July 2015 at 20:26.
    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
    Jun 2015
    Location
    India
    Posts
    185
    Thanks
    8
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: rowCount() is calling for all the top level items

    but when I test your new model I have seen all the top levels items rowsCount() is getting called, I am struggling exactly with this behavior only.

    Qt Code:
    1. int rowCount(const QModelIndex &parent = QModelIndex()) const
    2. {
    3. qDebug() << parent; //little change in debug msg
    4.  
    5. if(!parent.isValid()) return 10;
    6. if(parent.isValid() && !parent.parent().isValid()) return 2; // limit to two levels
    7.  
    8. return 0;
    9. }
    10.  
    11. int main(int argc, char **argv) {
    12. QApplication app(argc, argv);
    13. v.setFixedSize(200, 50); //set height to 50 so that view can accommodate 2 top level elements only
    14. Model model;
    15. v.setModel(&model);
    16. v.show();
    17. return app.exec();
    18. }
    To copy to clipboard, switch view to plain text mode 
    The out put I observed is :

    QModelIndex(-1,-1,0x0,QObject(0x0) )
    QModelIndex(-1,-1,0x0,QObject(0x0) )
    QModelIndex(-1,-1,0x0,QObject(0x0) )
    QModelIndex(0,0,0xffffffff,QAbstractItemModel(0x28 fe18) )
    QModelIndex(1,0,0xffffffff,QAbstractItemModel(0x28 fe18) )
    QModelIndex(2,0,0xffffffff,QAbstractItemModel(0x28 fe18) )
    QModelIndex(3,0,0xffffffff,QAbstractItemModel(0x28 fe18) )
    QModelIndex(4,0,0xffffffff,QAbstractItemModel(0x28 fe18) )
    QModelIndex(5,0,0xffffffff,QAbstractItemModel(0x28 fe18) )
    QModelIndex(6,0,0xffffffff,QAbstractItemModel(0x28 fe18) )
    QModelIndex(7,0,0xffffffff,QAbstractItemModel(0x28 fe18) )
    QModelIndex(8,0,0xffffffff,QAbstractItemModel(0x28 fe18) )
    QModelIndex(9,0,0xffffffff,QAbstractItemModel(0x28 fe18) )

    //rowCount() is getting called for all top level items here.

    One more thing I have observed is, When i return 10000000(top level items) in rowCount() (in old model you suggested & in new model also), My application got crashed with runtime error (on Windows 8, 64bit application).
    And when I return 1000000 row count & when I try to scroll down its hanging like hell, not able to scroll at all.
    Last edited by prasad_N; 9th July 2015 at 07:01.
    Thanks :-)

  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: rowCount() is calling for all the top level items

    Which Qt version are you using? How much RAM does your machine have?
    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
    Jun 2015
    Location
    India
    Posts
    185
    Thanks
    8
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: rowCount() is calling for all the top level items

    I am using 4.8.6 & 5.4.0 with windows 8 and 4GB RAM, I tested on both the versions it failed.
    Thanks :-)

  10. #10
    Join Date
    Jun 2015
    Location
    India
    Posts
    185
    Thanks
    8
    Thanked 14 Times in 14 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: rowCount() is calling for all the top level items

    Hi Any idea, why is this happening ?
    Thanks :-)

  11. #11
    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: rowCount() is calling for all the top level items

    4E9 bytes for 1E7 items yields 4E2 (=400) bytes per item. My guess is you are running out of memory
    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.


Similar Threads

  1. Replies: 10
    Last Post: 21st May 2015, 18:11
  2. Replies: 16
    Last Post: 12th May 2015, 21:46
  3. Replies: 1
    Last Post: 14th March 2013, 22:50
  4. QTreeWidget::findItems only searches top level items ?
    By krisha in forum Qt Programming
    Replies: 3
    Last Post: 27th October 2011, 08:28
  5. Replies: 4
    Last Post: 4th June 2007, 12:07

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.