Reputation: 29955
I have a Qt GUI application which does some I/O bound work when a button is pressed. In order to avoid GUI not being responsive, I created a new thread and move the work there:
private slots:
inline void on_process_button_clicked() const
{
std::thread thread(&My_class::on_process_button_clicked_real_work, this);
thread.detach();
}
I detach the thread immediately. The other function simply does the real work:
void on_process_button_clicked_real_work() const
{
std::lock_guard<std::mutex> lock(mutex);
// Some irrelevant code ...
}
The GUI now doesn't entirely freeze, I can still see it updated, but it becomes really unresponsive and laggy.
Questions:
1. Why does this happen?
2. How may I fix it?
I have seen many similar question, but most are about QThread
so I couldn't solve my problem.
Upvotes: 0
Views: 475
Reputation: 29955
Turns out the problem is I was using QFileSystemModel
(not in this function but in general) to show a list of files in the folder and this answer points out:
QFileSystemModel
lists directories on a background thread to avoid blocking the UI. However, once it gets a list of updates inQFileSystemModelPrivate::_q_fileSystemChanged
it then fetches the icons for the file in the main thread usingQFileInfoGatherer::getInfo()
which in turn callsQFileIconProvider::icon(QFileInfo)
.
The problem is that QFileSystemModel
constantly updates the GUI while the new thread rapidly creates/removes files and that causes the laggy experience. I don't know how to stop or delay updates in that model, but what I did is changing rootPath
to ""
and changing it back once the function finishes the work:
void on_process_button_clicked_real_work() const
{
std::lock_guard<std::mutex> lock(mutex);
auto path = model.rootPath();
model.setRootPath("");
// Some irrelevant code ...
model.setRootPath(path);
}
Implementing some kind of lock object to be exception safe and make sure the rootPath
is set back is probably the most optimal way.
Upvotes: 2