Solved UI blocking during update from slot
-
I have a
QTreeView
which is paired with aQStandardItemModel
and created in the main thread.
I have a worker thread running which is processing a lot of data and uses a signal/slot to update the model in the main thread. The slot in the main thread just basically appends a new row of items to the model:void MainWindow::slotAppendRow() noexcept { QList<QStandardItem*> items; items.append(new QStandardItem("1")); items.append(new QStandardItem("2")); items.append(new QStandardItem("3")); items.append(new QStandardItem("4")); m_treeModel.appendRow(items); }
I must be emitting about hundreds of signals every second and I'm noticing the interaction with the UI becomes really choppy/blocks sometimes while the slot is adding items to the model. I've tried to offload as much computation in the worker thread as possible but given that it's not possible to update the UI from a different thread in Qt, how can I make my GUI 100% responsive? I.e how can I prevent the GUI from blocking?
MainWindow.h
QStandardItemModel m_treeModel;
MainWindow.cpp
// Setup model MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ... m_ui->m_tree->setModel(&m_treeModel);
Where
m_tree
is aQTreeView
set in the form designer. -
@Nubcake said in UI blocking during update from slot:
How do you signal the view to update the change in the model? -
@nagesh I don't actually, it updates by itself it seems.
-
@Nubcake some more code snippet is required to answer what is wrong in GUI update.
treeModel construction and setup with view. -
@nagesh Updated original post with the setup
-
@Nubcake confirm whether your computation and gui update is happening in different thread by printing threadid..
-
Don't use a convenience model when you want to upgrade stuff that often. Also reduce the update rate - noone can see this in the view so it's not necessary.
-
@Christian-Ehrlicher Could you explain what you mean by "convenience model"?
How often should I update the view would you suggest? -
QStandardItemModel is a convenience model optimized for general usage but not for mass (update) data. Use QAbstractItemModel instead.
I don't know how often you should update your ui - but 100 updates per second is for sure not needed and to much. -
@Christian-Ehrlicher I've added
QThread::msleep(50)
just after emitting the signal to update the UI in the worker thread and it's more responsive as one would expect.However I'm not fond of blocking the worker thread to allow the GUI to become responsive. Is there better way to limit the amount of signals I send to the UI without sleeping the worker thread?
-
@Nubcake
Emit less signals from the worker. Or, probably better, reduce the frequency with which you act on them in the UI thread, or batch some updates together, or similar.