Results 1 to 2 of 2

Thread: Flickering in QListView when appending items if VerticalScrollBarPolicy == AlwaysOff

  1. #1
    Join Date
    Aug 2007
    Posts
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Flickering in QListView when appending items if VerticalScrollBarPolicy == AlwaysOff

    Hi!

    I have a QListView whose model is getting items appended from a worker thread (as discussed here: https://forum.qt.io/topic/98481/ui-r...ata-into-model). After implementing this in my actual program I noticed the listview flickering a lot while items were being added. After some testing I found that removing the call to QListView::setVerticalScrollBarPolicy(Qt::ScrollBa rAlwaysOff) removed all the flickering. I have made a little video showing this. I do not have the privileges to upload it here directly, but I've posted it here: https://gfycat.com/LivelyAptCassowary. At the start of the video, everything is fine with the scrollbar present, then without the scrollbar the list is barely usable while items are added.

    It looks to me like the QListView is doing a lot of extra (unnecessary) repaints when the scrollbar is not there. I almost think this might be a bug, but maybe I'm just being stupid or missing something obvious. Does anyone know what's going on?

    Also, is there a workaround? Any classes or functions to reimplement?

    The code I used:
    Qt Code:
    1. //main.cc
    2. #include <QtWidgets>
    3.  
    4. #include "myitemmodel.h"
    5.  
    6. int main(int argc, char *argv[])
    7. {
    8. QApplication app(argc, argv);
    9. QWidget widget;
    10.  
    11. QVBoxLayout *layout = new QVBoxLayout(&widget);
    12. QListView *listview = new QListView(&widget);
    13. QPushButton *button = new QPushButton("Populate list", &widget);
    14.  
    15. MyItemModel *model = new MyItemModel;
    16.  
    17. listview->setModel(model);
    18. listview->setMouseTracking(true);
    19. listview->setEditTriggers(QListView::NoEditTriggers);
    20. listview->setResizeMode(QListView::Adjust);
    21. listview->setWordWrap(true);
    22. listview->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
    23. listview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    24.  
    25. listview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // <-- PROBLEM!
    26.  
    27. QObject::connect(button, &QPushButton::clicked, model, &MyItemModel::loadData);
    28.  
    29. layout->addWidget(listview);
    30. layout->addWidget(button);
    31.  
    32. widget.setMinimumSize(QSize(320, 380));
    33.  
    34. widget.show();
    35. return app.exec();
    36. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. //myitemmodel.h
    2. #ifndef MYITEMMODEL_H_
    3. #define MYITEMMODEL_H_
    4.  
    5. #include <QtWidgets>
    6.  
    7. class MyItemModel : public QStandardItemModel
    8. {
    9. Q_OBJECT;
    10.  
    11. bool d_cancel;
    12. QThread *d_worker;
    13.  
    14. public:
    15. inline MyItemModel(QWidget *parent = nullptr);
    16. public slots:
    17. inline void loadData();
    18. inline void addAvailableItem(QStandardItem *item);
    19. signals:
    20. void itemAvailable(QStandardItem *item);
    21. private:
    22. inline void loadDataWorker();
    23. };
    24.  
    25. inline MyItemModel::MyItemModel(QWidget *parent)
    26. :
    27. d_cancel(false),
    28. d_worker(nullptr)
    29. {
    30. connect(this, &MyItemModel::itemAvailable, this, &MyItemModel::addAvailableItem, Qt::QueuedConnection);
    31. }
    32.  
    33. inline void MyItemModel::loadData()
    34. {
    35. // here, I should cancel any running threads and wait for them to stop
    36. d_cancel = true;
    37. if (d_worker)
    38. {
    39. d_worker->wait();
    40. delete d_worker;
    41. d_worker = nullptr;
    42. }
    43. d_cancel = false;
    44.  
    45. // clear the model
    46. clear();
    47.  
    48. // start thread to load data
    49. d_worker = QThread::create([=]{loadDataWorker();});
    50. d_worker->start();
    51. }
    52.  
    53. inline void MyItemModel::loadDataWorker()
    54. {
    55. for (uint i = 0; i < 2000; ++i)
    56. {
    57. if (d_cancel)
    58. break;
    59.  
    60. item->setData("This is item " + QString::number(i), Qt::DisplayRole);
    61. QThread::msleep(2);
    62.  
    63. emit itemAvailable(item);
    64. }
    65. }
    66.  
    67. inline void MyItemModel::addAvailableItem(QStandardItem *item)
    68. {
    69. appendRow(item);
    70. }
    71.  
    72. #endif
    To copy to clipboard, switch view to plain text mode 

    Should compile with qmake -project QT+=widgets && qmake && make.

    Thanks!

  2. #2
    Join Date
    Aug 2007
    Posts
    6
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: Flickering in QListView when appending items if VerticalScrollBarPolicy == Always

    I tried to work around this issue by hiding the scrollbar by setting its width to zero. Unfortunately using QListView::verticalScrollBar()->setStyleSheet("QScrollBar {width:0px;}"); produces the exact same flickering as calling QListView::setVerticalScrollBarPolicy(Qt::ScrollBa rAlwaysOff), while setting to 1px works flawlessly (with a weirdly slim scrollbar).

    Any workaround suggestion is still highly appreciated.

Similar Threads

  1. Removing all Items from QListView
    By subrat17june in forum Qt Programming
    Replies: 1
    Last Post: 6th June 2013, 12:07
  2. Add Items to QListView
    By gaganbm in forum Newbie
    Replies: 5
    Last Post: 2nd December 2012, 00:28
  3. QListView - adding items
    By creep33 in forum Qt Programming
    Replies: 3
    Last Post: 9th September 2010, 18:30
  4. How to reorder items in QListView?
    By xfurrier in forum Qt Programming
    Replies: 2
    Last Post: 12th August 2009, 17:09
  5. moving Qlistview items
    By :db:sStrong in forum Qt Programming
    Replies: 0
    Last Post: 21st February 2006, 13:25

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.