Qt GUI зависает несмотря на многопоточность - PullRequest
0 голосов
/ 13 апреля 2019

У меня есть приложение Qt GUI, которое выполняет некоторые операции ввода-вывода при нажатии кнопки.Чтобы не реагировать на 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 ...
}

Графический интерфейс пользователя теперь не полностью зависает, я все еще вижу его обновленным, но он становится действительно не отвечающим и медленным.

Вопросы:
1. Почему это происходит?
2. Как я могу это исправить?

Я видел много похожих вопрос , но большинство из них о QThread, поэтому я не мог решить свою проблему.

1 Ответ

2 голосов
/ 13 апреля 2019

Оказывается, проблема в том, что я использовал QFileSystemModel (не в этой функции, а в общем), чтобы показать список файлов в папке, и этот ответ указывает:

QFileSystemModel перечисляет каталоги в фоновом потоке, чтобы избежать блокировка пользовательского интерфейса. Однако, как только он получает список обновлений в QFileSystemModelPrivate::_q_fileSystemChanged затем получает иконки для файла в основном потоке с помощью QFileInfoGatherer::getInfo() который в свою очередь вызывает QFileIconProvider::icon(QFileInfo).

Проблема в том, что QFileSystemModel постоянно обновляет графический интерфейс, в то время как новый поток быстро создает / удаляет файлы, что приводит к запаздыванию. Я не знаю, как остановить или задержать обновления в этой модели, но я изменил 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, возможно, является наиболее оптимальным способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...