尽管有线程,Qt GUI 仍挂起



我有一个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. 我该如何解决?

我见过很多类似的问题,但大多数都是关于QThread所以我无法解决我的问题。

事实证明,问题是我正在使用QFileSystemModel(不是在此函数中,而是在一般情况下(来显示文件夹中的文件列表,并且此答案指出:

QFileSystemModel列出后台线程上的目录以避免 阻止 UI。但是,一旦它获得更新列表 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被设置可能是最佳方法。

最新更新