我有一个Qt GUI应用程序,当按下按钮时,它可以完成一些I / O绑定工作。为了避免GUI无法响应,我创建了一个新线程并将工作移到那里:
private slots:
inline void on_process_button_clicked() const
{
std::thread thread(&My_class::on_process_button_clicked_real_work, this);
thread.detach();
}
我立即分离线程。另一个功能只是完成实际工作:
void on_process_button_clicked_real_work() const
{
std::lock_guard<std::mutex> lock(mutex);
// Some irrelevant code ...
}
现在,GUI并没有完全冻结,我仍然可以看到它已更新,但是它变得反应迟钝和缓慢。
问题:
1.为什么会这样?
2.我该如何解决?
答案 0 :(得分:2)
原来的问题是我正在使用QFileSystemModel
(不是在此功能中,而是在一般情况下)显示文件夹中的文件列表,并且this答案指出:
QFileSystemModel
在后台线程上列出目录以避免 阻止用户界面。但是,一旦获得更新列表QFileSystemModelPrivate::_q_fileSystemChanged
,然后获取 主线程中文件的图标使用QFileInfoGatherer::getInfo()
依次调用QFileIconProvider::icon(QFileInfo)
。
问题在于QFileSystemModel
会不断更新GUI,而新线程会快速创建/删除文件,这会导致运行缓慢。我不知道如何在该模型中停止或延迟更新,但是我所做的是将rootPath
更改为""
,并在函数完成工作后将其更改回:
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);
}
实现某种锁定对象以确保异常安全并确保将rootPath
放回原处可能是最佳方法。