Results 1 to 17 of 17

Thread: Time taken to populate QTableWidget differs based on where I am in the app

  1. #1
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Time taken to populate QTableWidget differs based on where I am in the app

    I observed an interesting thing today. In my app, a certain windows has a tabbed interface (QTabWidget). There are three tabs, and in one of the three tab widgets, there is QTableWidget. Which is populated with rows of data when the user wants some information and clicks a button. Now for certain kind of queries the number of rows is huge, say 3000~4000. A simple qDebug() prints out all the 4000 rows almost instantly, but it takes upto 2-3 minutes for all the 4000 rows to be populated in the QTableWidget UI. That tells me that the time is not being taken to generate the data, time is taken to populate the table with so many rows. Which is justified.

    Today, after I queried for one such data, I switched to another tab to check out something. When I switched back to the tablewidget tab, I found that all 4000 rows have been populated! I have been to the other tab for 5~6 seconds, and it generally takes 3 minutes for all rows to come up when I am in the tablewidget tab all through!

    Why is this happening? I suspect something along the lines of the UI thread being changed to accommodate my viewing the new tab, and delegating the tablewidget tab to another thread which does it fast in the background. Is there something more to it? Can I tap this feature to ensure that the populating is done in 5 seconds always, no mater where I am?

  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: Time taken to populate QTableWidget differs based on where I am in the app

    First of all QTableWidget is not suited to situations when it has to hold that much data, you should rather use a model based approach. Second, you are asking this one by one possibly with having sorting or filtering applied or with column width fixed to size of its contents. One or more of these causes a costly operation to be performed after each of the rows is inserted. It's much better to insert all rows in one batch. This is again possible when using a regular 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.


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

    Cupidvogel (24th May 2015)

  4. #3
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Time taken to populate QTableWidget differs based on where I am in the app

    My column width is fixed. It doesn't depend on the content of the rows that are being populated one by one.

    In our app, it is not feasible to populate all data in one go. Sometimes the total number of results may take say 5 seconds to collect, and we don't want the user to wait until 5 seconds before he sees all results at once. Instead it's better to display results on the fly when they are available.

    But why does it perform so faster when I switch to another tab?

  5. #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: Time taken to populate QTableWidget differs based on where I am in the app

    Quote Originally Posted by Cupidvogel View Post
    In our app, it is not feasible to populate all data in one go. Sometimes the total number of results may take say 5 seconds to collect, and we don't want the user to wait until 5 seconds before he sees all results at once. Instead it's better to display results on the fly when they are available.
    5 seconds for 4000 rows gives about 1 record per 1 ms. You don't have to update every 1ms, do you? You can surely update in batches of 1000 every second.

    But why does it perform so faster when I switch to another tab?
    The view is not displayed which leads me to the conclusion that your column width is not as fixed as you think.
    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. The following user says thank you to wysota for this useful post:

    Cupidvogel (24th May 2015)

  7. #5
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Time taken to populate QTableWidget differs based on where I am in the app

    Quote Originally Posted by Cupidvogel View Post
    But why does it perform so faster when I switch to another tab?
    A widget that is not visible doesn't have to do any updating when the data it displays changes.
    A visible widget does.

    Cheers,
    _

  8. The following user says thank you to anda_skoa for this useful post:

    Cupidvogel (24th May 2015)

  9. #6
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Time taken to populate QTableWidget differs based on where I am in the app

    Thanks guys. I will display my code which does it, you decide whether the column width is fixed or not (yeah, I am setting the button's length on the fly because I need to elide the text):

    Qt Code:
    1. //QueryView class
    2.  
    3. void QueryView::initUI()
    4. {
    5. queryButton = new QPushButton(this);
    6. textBox = new QLineEdit(this);
    7. /* ---other UI code --- */
    8.  
    9. fTableWidget = new QTableWidget(1,2,this);
    10. fTableWidget->setGeometry(15,169,251,232);
    11. fTableWidget->setColumnWidth(0,198);
    12. fTableWidget->setColumnWidth(1,54);
    13. fTableWidget->setFrameStyle(QFrame::NoFrame);
    14. fTableWidget->setShowGrid(false);
    15. fTableWidget->horizontalHeader()->hide();
    16. fTableWidget->verticalHeader()->hide();
    17. fTableWidget->verticalHeader()->setDefaultSectionSize(24);
    18. fTableWidget->setObjectName("fTableWidget");
    19. fTableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    20. }
    21.  
    22. void QueryVieww::bindSignalsAndSlots()
    23. {
    24. connect(queryButton, SIGNAL(clicked()), this, SLOT(doQuery()));
    25. }
    26.  
    27. void QueryView::doQuery()
    28. {
    29. QString text = textBox->text();
    30. QueryAction *action = new QueryAction(text, this);
    31. action->execute();
    32. }
    33.  
    34. void QueryView::updateTable(QString text1, QString text2)
    35. {
    36. int rowNum = fTableWidget->rowCount();
    37. fTableWidget->setRowCount(rowNum+1);
    38.  
    39. QPushButton *textSnippet = new QPushButton();
    40. textSnippet->setStyleSheet("text-align: left; border: none; padding-left: 10px;");
    41. textSnippet->setCursor(Qt::PointingHandCursor);
    42. textSnippet->setFixedHeight(24);
    43. textSnippet->setFixedWidth(198);
    44.  
    45. QPushButton *button2 = new QPushButton();
    46. button2->setStyleSheet("text-align: left; border: none; padding-left: 10px;");
    47. button2->setCursor(Qt::PointingHandCursor);
    48. button2->setFixedHeight(24);
    49. button2->setFixedWidth(54);
    50. button2->setText(text2);
    51.  
    52. fTableWidget->setCellWidget(rowNum,0,textSnippet);
    53. fTableWidget->setCellWidget(rowNum,1,button2);
    54.  
    55.  
    56. //here text is added last because ellipsis text needs the width of the button, so first attaching it to the view,
    57. //then extracting its width and showing ellipsis at 5 px from the end, i.e 198-5 = 193
    58. QFontMetrics metrics(textSnippet->font());
    59. QString elidedText = metrics.elidedText(text1, Qt::ElideRight, 193);
    60. textSnippet->setText(elidedText);
    61.  
    62. }
    63.  
    64. //QueryAction class
    65.  
    66. QueryAction::QueryAction(QString queryText, QueryView *view)
    67. {
    68. fQueryText = queryText;
    69. fView = view;
    70. }
    71.  
    72. QueryAction::execute()
    73. {
    74. //search a binary tree with queryText, if query matches, update view immediately
    75. while (rootNode != NULL)
    76. {
    77. data = rootNode.data;
    78. if (data.text == fQueryText)
    79. {
    80. fView->updateTable(data.keyData, data.valueData);
    81. }
    82. //traverse to left and right of rootNode
    83. }
    84. }
    To copy to clipboard, switch view to plain text mode 

    And I also verified whether doing it in one go gives me better performance by modifying the execute method like this:

    Qt Code:
    1. QueryAction::execute()
    2. {
    3. //search a binary tree with queryText, if query matches, update view immediately
    4. std::vector<RootNode.Data> temp;
    5. while (rootNode != NULL)
    6. {
    7. data = rootNode.data;
    8. if (data.text == fQueryText)
    9. {
    10. //commented out, no updating on the fly
    11. //fView->updateTable(data.keyData, data.valueData);
    12. temp.push_back(data);
    13. }
    14. //traverse to left and right of rootNode
    15. }
    16.  
    17. //now that all the data are there, populate UI in one go
    18. for (int i = 0; i < temp.size(); i++)
    19. fView->updateTable(temp[i]);
    20. }
    To copy to clipboard, switch view to plain text mode 

    This does give me a better performance, but pretty marginal, by about 10%. The queries which were taking say 2 minutes to populate (around 3500 rows) are now taking 1 minute 50 seconds (I am discounting the initial time gap after the button is clicked because the results are being cached first. I started counting time only when the first row was populated, so that I can find out the exact time taken to populate all rows). Whereas switching the tab was doing it in 5-6 seconds.

  10. #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: Time taken to populate QTableWidget differs based on where I am in the app

    Using cell widgets has very negative impact on performance, those buttons do not have any signals connected to them so I don't understand why you are using them at all instead of setting data directly on the item (or the model). Off the top of my head I will not say whether the fixed size you set on the buttons is respected by the view or not but surely your columns are not fixed, you can grab the header and resize it (yes, I know you are hiding the header but it doesn't make the columns fixed size).
    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.


  11. The following user says thank you to wysota for this useful post:

    Cupidvogel (24th May 2015)

  12. #8
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Time taken to populate QTableWidget differs based on where I am in the app

    Oh, yes, I am sorry, I forgot to include the signal connection for the rows. Here is the revised method:

    Qt Code:
    1. void QueryView::updateTable(QString text1, QString text2)
    2. {
    3. int rowNum = fTableWidget->rowCount();
    4. fTableWidget->setRowCount(rowNum+1);
    5.  
    6. QPushButton *textSnippet = new QPushButton();
    7. textSnippet->setStyleSheet("text-align: left; border: none; padding-left: 10px;");
    8. textSnippet->setCursor(Qt::PointingHandCursor);
    9. textSnippet->setFixedHeight(24);
    10. textSnippet->setFixedWidth(198);
    11. textSnippet->setProperty("data",text1);
    12.  
    13. QPushButton *button2 = new QPushButton();
    14. button2->setStyleSheet("text-align: left; border: none; padding-left: 10px;");
    15. button2->setCursor(Qt::PointingHandCursor);
    16. button2->setFixedHeight(24);
    17. button2->setFixedWidth(54);
    18. button2->setText(text2);
    19. button->setProperty("data",text2);
    20.  
    21. fTableWidget->setCellWidget(rowNum,0,textSnippet);
    22. fTableWidget->setCellWidget(rowNum,1,button2);
    23.  
    24.  
    25. //here text is added last because ellipsis text needs the width of the button, so first attaching it to the view, then extracting its width and showing
    26. //ellipsis at 5 px from the end, i.e 198-5 = 193
    27. QFontMetrics metrics(textSnippet->font());
    28. QString elidedText = metrics.elidedText(text1, Qt::ElideRight, 193);
    29. textSnippet->setText(elidedText);
    30.  
    31. //connect both columns to the same method
    32. connect(textSnippet, SIGNAL(clicked()), this, SLOT(showAlert()));
    33. connect(button2, SIGNAL(clicked()), this, SLOT(showAlert()));
    34.  
    35. }
    To copy to clipboard, switch view to plain text mode 

    I didn't get what you said about the column size. I am setting the column size width fixed in the initUI method, right? I am specifying the height and width for each button because I need it to elide text, which needs a fixed width to work. If cellwidgets have negative impact what other way can I do this task?
    Last edited by Cupidvogel; 24th May 2015 at 21:50.

  13. #9
    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: Time taken to populate QTableWidget differs based on where I am in the app

    Quote Originally Posted by Cupidvogel View Post
    Oh, yes, I am sorry, I forgot to include the signal connection for the rows.
    And what are you going to connect them to in your real code?

    I didn't get what you said about the column size. I am setting the column size width fixed in the initUI method, right?
    I don't see any call in there that would do that.

    If cellwidgets have negative impact what other way can I do this task?
    Well... QTableWidgetItem::setText() would be my first choice
    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.


  14. #10
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Time taken to populate QTableWidget differs based on where I am in the app

    The 9th and 10th lines of my initUI code:

    Qt Code:
    1. fTableWidget = new QTableWidget(1,2,this);
    2. fTableWidget->setGeometry(15,169,251,232);
    3. fTableWidget->setColumnWidth(0,198);
    4. fTableWidget->setColumnWidth(1,54);
    To copy to clipboard, switch view to plain text mode 

    Yes, I may change it to QTableWidgetItem, change the clicked event to cell clicked event of the table widget itself. But again, will that increase the performance significantly? Like switching tab here does? I want that performance.

    Upon clicking, I get the data associated with that row (as data1 and data2), which we use to take the user to certain part of the document where the query value is showing (think of it as an inline Google app. ), or show an alert if it is not available for some reason.

  15. #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: Time taken to populate QTableWidget differs based on where I am in the app

    Quote Originally Posted by Cupidvogel View Post
    The 9th and 10th lines of my initUI code:

    Qt Code:
    1. fTableWidget = new QTableWidget(1,2,this);
    2. fTableWidget->setGeometry(15,169,251,232);
    3. fTableWidget->setColumnWidth(0,198);
    4. fTableWidget->setColumnWidth(1,54);
    To copy to clipboard, switch view to plain text mode 
    That doesn't say anything to be "fixed".

    But again, will that increase the performance significantly?
    Yes.

    I want that performance.
    Use a real model and insert data in batches instead of a series of single inserts.

    Upon clicking, I get the data associated with that row (as data1 and data2), which we use to take the user to certain part of the document where the query value is showing (think of it as an inline Google app. ), or show an alert if it is not available for some reason.
    Ok but why a button?
    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.


  16. #12
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Time taken to populate QTableWidget differs based on where I am in the app

    I needed to get the click event. Now that I see the table widget has a cell clicked event, I can try that as well. The second code sample I gave did all the updating in one go, right? But like I said that was faster by only around 10%. So okay, I will try the same in one go chunk updating with the table widget item, will see whether performance improves drastically or not..

    And I thought setting the column width fixed it? What else do you mean by 'fixed'?

    Do you mean this - http://stackoverflow.com/questions/9...f-qtablewidget ?
    Last edited by Cupidvogel; 24th May 2015 at 22:09.

  17. #13
    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: Time taken to populate QTableWidget differs based on where I am in the app

    Quote Originally Posted by Cupidvogel View Post
    The second code sample I gave did all the updating in one go, right?
    This one?

    Qt Code:
    1. for (int i = 0; i < temp.size(); i++)
    2. fView->updateTable(temp[i]);
    To copy to clipboard, switch view to plain text mode 

    No. This loops over all items to be inserted and adds them one by one here:
    Qt Code:
    1. fTableWidget->setRowCount(rowNum+1);
    To copy to clipboard, switch view to plain text mode 

    You would need to call this function once for the whole update. But in general as I wrote in the very beginning you will not be able to do it properly with QTableWidget. You would have to implement a proper model (subclass of QAbstractItemModel) and use QTableView instead of QTableWidget.

    And I thought setting the column width fixed it? What else do you mean by 'fixed'?
    I mean QHeaderView::​setSectionResizeMode() with QHeaderView::Fixed. And the consequences for Qt code paths this bears.
    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.


  18. The following user says thank you to wysota for this useful post:

    Cupidvogel (24th May 2015)

  19. #14
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Time taken to populate QTableWidget differs based on where I am in the app

    Okay. I have never used QTableView with a model before, so will take some time to reimplement my working. Can I make it look just like the table widget?

    And secondly, if I am doing it through a model, then I will have to insert all the data into the model one by one right like I was updating the rows here one by one, like here - http://doc.qt.digia.com/4.6/sql-presenting.html? Won't that take as much time as inserting the rows? Or is it that because it is a data model and not an UI element, inserting 4000 rows will be kind of instantaneous?

  20. #15
    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: Time taken to populate QTableWidget differs based on where I am in the app

    Quote Originally Posted by Cupidvogel View Post
    Can I make it look just like the table widget?
    Have a look what is the base class of QTableWidget.

    And secondly, if I am doing it through a model, then I will have to insert all the data into the model one by one right like I was updating the rows here one by one
    No. You can turn an empty model into an infinite one in an instance.
    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.


  21. The following user says thank you to wysota for this useful post:

    Cupidvogel (25th May 2015)

  22. #16
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Time taken to populate QTableWidget differs based on where I am in the app

    Okay. Will try it then and let you know.

  23. #17
    Join Date
    May 2014
    Posts
    136
    Thanks
    72
    Qt products
    Qt3 Qt4 PyQt3 PyQt4
    Platforms
    MacOS X Windows

    Default Re: Time taken to populate QTableWidget differs based on where I am in the app

    Thanks guys. I updated my code to do it via QTableView model based design. It now updates tens and thousands of rows in the blink of an eye! This is severely cool..

Similar Threads

  1. How to sort images in Qt based on Time
    By iswaryasenthilkumar in forum Newbie
    Replies: 4
    Last Post: 11th February 2015, 11:10
  2. Populate QTableWidget
    By ruben.rodrigues in forum Qt Programming
    Replies: 2
    Last Post: 3rd May 2011, 14:21
  3. how to populate data in QTableWidget
    By gauravg in forum Qt-based Software
    Replies: 1
    Last Post: 25th March 2011, 12:50
  4. PyQt Populate a QTableWidget
    By n3wcr4zy in forum Newbie
    Replies: 0
    Last Post: 2nd March 2011, 08:20
  5. Replies: 3
    Last Post: 1st February 2011, 11:57

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.