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!