0

我有一个 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所以我无法解决我的问题。

4

1 回答 1

2

原来问题是我正在使用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其设置回可能是最佳方式。

于 2019-04-13T14:49:13.593 回答