Results 1 to 5 of 5

Thread: speed of setdata - lots of items in treeview

  1. #1
    Join Date
    May 2006
    Posts
    28
    Thanks
    8
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default speed of setdata - lots of items in treeview

    Hi all,

    I need to populate the standardItemModel for my treeView, with possibly upto 300,000 rows.

    My treeView acts like a TableView, I guess I could use TableView if its quicker, as there is a flat hierarchy of items.

    At the moment 30,000 rows can take 5-6 seconds, which is unacceptable.
    I'm pretty sure I'm doing something sub-optimal.
    Thus why the need for a progress bar.

    Any suggestions please.

    Qt Code:
    1. treeView = new QTreeView;
    2. model = new QStandardItemModel(0,13);
    3. treeView->setModel(model);
    4.  
    5. void GamesTab::showMatches()
    6. {
    7. treeView->setUpdatesEnabled (false);
    8.  
    9. modelindex = model->index(0, 0, modelindex);
    10. model->insertRows(0, mainBoard->filteredResults.size(), modelindex);
    11. QVariant data;
    12.  
    13. QString number =
    14. for (unsigned int i = 0; i < mainBoard->filteredResults.size(); i++) {
    15. int db = mainBoard->filteredResults[i]->dbIndex;
    16. int game = mainBoard->filteredResults[i]->gameIndex;
    17. gamePtr = dbManager_->databases[db]->database->Games[game];
    18.  
    19. data = (dbManager_->databases[db]->name).c_str();
    20. model->setData(model->index(i, headerPosDatabase_, modelindex), data);
    21. data = (gamePtr->getPlayerW()).c_str();
    22. model->setData(model->index(i, headerPosPlayerWhite_, modelindex), data);
    23. data = (gamePtr->getPlayerB()).c_str();
    24. model->setData(model->index(i, headerPosPlayerBlack_, modelindex), data);
    25. data = (gamePtr->getRankW()).c_str();
    26. model->setData(model->index(i, headerPosRankWhite_, modelindex), data);
    27. data = (gamePtr->getRankB()).c_str();
    28. model->setData(model->index(i, headerPosRankBlack_, modelindex), data);
    29. data = (gamePtr->getResultStr()).c_str();
    30. model->setData(model->index(i, headerPosResult_, modelindex), data);
    31. data = (gamePtr->getKomi()).c_str();
    32. model->setData(model->index(i, headerPosKomi_, modelindex), data);
    33. data = (gamePtr->getDate()).c_str();
    34. model->setData(model->index(i, headerPosDate_, modelindex), data);
    35. data = gamePtr->getMoveCount();
    36. model->setData(model->index(i, headerPosMoveCount_, modelindex), data);
    37. data = (gamePtr->getHandicap()).c_str();
    38. model->setData(model->index(i, headerPosHandicap_, modelindex), data);
    39. data = (gamePtr->getPlace()).c_str();
    40. model->setData(model->index(i, headerPosPlace_, modelindex), data);
    41. data = (gamePtr->getEvent()).c_str();
    42. model->setData(model->index(i, headerPosEvent_, modelindex), data);
    43.  
    44. progressBar_->setValue(i + 1);
    45. }
    46.  
    47. treeView->setUpdatesEnabled (true);
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: speed of setdata - lots of items in treeview

    Quote Originally Posted by Big Duck
    At the moment 30,000 rows can take 5-6 seconds, which is unacceptable.
    How long does it take when you replace all "(...).c_str()" with some constant string?

    Model has to emit appropriate signals each time it is changed, if you would write your own model, you could populate it in one go (without using setData() and emitting signals for each item).

    Quote Originally Posted by Big Duck
    Thus why the need for a progress bar.
    While your program updates the model, Qt can't process events, so to make your progress bar work you have to invoke QCoreApplication::processEvents().

  3. The following user says thank you to jacek for this useful post:

    Big Duck (5th July 2006)

  4. #3
    Join Date
    May 2006
    Posts
    28
    Thanks
    8
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: speed of setdata - lots of items in treeview

    I tried using a tableView instead of a TreeView and there was no speed difference.

    I tried replacing "(...).c_str()" with some constant string and it makes very little difference to the time, it still is about 5 seconds for 30,000 rows.


    Model has to emit appropriate signals each time it is changed, if you would write your own model, you could populate it in one go (without using setData() and emitting signals for each item).
    Sounds good to me ! If I dont use setData, how would I go about writing my own Model ? Subclassing StandardItemModel or perhaps AbstarctItemModel ?

    Would I implement a function to use SetData within the subclassed model and somehow turn off signals being emitted ?

    Thanks for setting me on the right track.

  5. #4
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    5,372
    Thanks
    28
    Thanked 976 Times in 912 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: speed of setdata - lots of items in treeview

    Quote Originally Posted by Big Duck
    I tried replacing "(...).c_str()" with some constant string and it makes very little difference to the time, it still is about 5 seconds for 30,000 rows.
    So the problem is most likely with setData().

    Quote Originally Posted by Big Duck
    If I dont use setData, how would I go about writing my own Model ? Subclassing StandardItemModel or perhaps AbstarctItemModel ?
    IMO the easiest way is to subclass QAbstractTableModel --- there are instructions in the docs how to do it (just don't forget to invoke beginInsertRow() and endInsertRows() when you add rows to your model).

    You need setData() only if you want your users to change the model contents using a view. If users only view the data, you don't need it at all.

    Few examples:
    Qt Code:
    1. int SomeModel::rowCount( const QModelIndex& parent ) const
    2. {
    3. if( ! parent.isValid() ) { // someone wants to know the number of rows of top-level items
    4. return _data.size(); // get the number of items in the vector, list or whatever collection you will use
    5. }
    6. else {
    7. return 0; // since we don't have any children (there is only one layer of items in the model)
    8. }
    9. }
    10.  
    11.  
    12. QVariant SomeModel::data( const QModelIndex& index,
    13. int role ) const
    14. {
    15. if( index.isValid() ) {
    16.  
    17. // find the right item
    18.  
    19. switch( role ) {
    20.  
    21. case Qt::DisplayRole: // data that should be diplayed in cell (index.row(), index.column())
    22. {
    23. switch( index.column() ) { // or simply: return item.property( index.column() );
    24. case Something:
    25. return item.something();
    26.  
    27. case SomethingDifferent:
    28. return item.somethingDifferent();
    29.  
    30. default:
    31. return QVariant();
    32. }
    33. break;
    34. }
    35. // and so on
    36. }
    37. }
    38. return QVariant();
    39. }
    To copy to clipboard, switch view to plain text mode 

  6. The following user says thank you to jacek for this useful post:

    Big Duck (5th July 2006)

  7. #5
    Join Date
    May 2006
    Posts
    28
    Thanks
    8
    Thanked 3 Times in 2 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: speed of setdata - lots of items in treeview [SOLVED]

    Hi, just wanted to say a big thank you for solving this.

    It now takes 0 seconds to display 30,000 rows in the TableView, by subclassing an AbstractTableModel.
    I am now starting to understand the power of a MVC design!

    I never thought it would work but wow, its fast.

    Below is some code in case it helps someone to do the same:

    Qt Code:
    1. int ResultsModel::rowCount(const QModelIndex &parent) const
    2. {
    3. filteredResults.size();
    4. }
    5.  
    6.  
    7.  
    8. int ResultsModel::columnCount(const QModelIndex &parent) const
    9. {
    10. return 13;
    11. }
    12.  
    13.  
    14.  
    15.  
    16. QVariant ResultsModel::data(const QModelIndex &index, int role) const
    17. {
    18.  
    19. QVariant data;
    20.  
    21. if (!index.isValid()) {
    22. return QVariant();
    23. }
    24.  
    25. if (index.row() >= filteredResults.size()) {
    26. return QVariant();
    27. }
    28.  
    29. if (index.column() >= 13) {
    30. return QVariant();
    31. }
    32.  
    33. if (role == Qt::DisplayRole) {
    34. int db = mainBoard->filteredResults[index.row()]->dbIndex;
    35. int game = mainBoard->filteredResults[index.row()]->gameIndex;
    36. boost::shared_ptr<Game> gamePtr = mainWindow_->dbManager_->databases[db]->database->Games[game];
    37.  
    38. switch (index.column()) {
    39. case 0 : {
    40. data = (mainWindow_->dbManager_->databases[db]->name).c_str();
    41. return data;
    42. }
    43. case 1 : {
    44. data = (gamePtr->getPlayerW()).c_str();
    45. return data;
    46. break;
    47. }
    48. case 2 : {
    49. data = (gamePtr->getPlayerB()).c_str();
    50. return data;
    51. break;
    52. }
    53.  
    54. // ETC ETC
    55.  
    56. }
    57. }
    58. // else
    59. return QVariant();
    60. }
    To copy to clipboard, switch view to plain text mode 

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.