I am facing strange thing with dynamically adding items to my QStandardItemModel and showing them with QTableView. If the time between events is long enough (like 50 ms) then the view is scrollable, but in case of faster event (10 ms) the view always scrolls down and doesn't allow me to do anything.
So here is the simple code snippet:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#include <QMainWindow>
#include <QTimer>
#include <QTableView>
#include <QStandardItemModel>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QTimer dataTimer;
QStandardItemModel *model;
QTableView *view;
public slots:
void insertData();
};
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTime>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
view = new QTableView(this);
this->setCentralWidget(view);
model = new QStandardItemModel(this);
model->setColumnCount(1);
view->setModel(model);
QObject::connect(&dataTimer, &QTimer::timeout, this, &MainWindow::insertData);
dataTimer.start(10); // 50 here gives correct behaviour while 10 does not
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::insertData()
{
QList<QStandardItem *> items;
items.append(new QStandardItem(QTime::currentTime().toString("hh:mm:ss.zzz")));
model->insertRow(0, items);
if (model->rowCount() > 20){
model->removeRow(model->rowCount()-1);
}
}
dataTimer.start(50) works fine, while dataTimer.start(10) brakes behavior. It is for my laptop and maybe for someone else the numbers will be different but I think logic is clear.
I was thinking that it is kind of too fast and some methods like beginInsertRows() doesn't work well. But that is for custom models usually and here it is just a standard one.
Can someone tell me why that happens? Thank you
10 ms timer in a GUI thread to affect GUI elements is a bad idea itself. For example, in Windows 10 ms timeout is unattainable by standard means. Does your user really need to see updates of some table data more than 1 time per second? What does he really need? Based on this, you should determine an optimization method.
Then you could choose:
model->setRowCount(n)
;Temporarily disable table refresh by setUpdatesEnabled() method:
setUpdatesEnabled(false);
bigVisualChanges();
setUpdatesEnabled(true);
Sublass one of the Qt model classes and reimplement insertRows() or something more.