Qt C ++ «keine Rückmeldung» — ошибка в графическом интерфейсе при длительных расчетах

У меня есть вопрос по поводу длинных расчетов:

При выполнении некоторых задач моего графического интерфейса могут быть сделаны длинные расчеты. Это не проблема, это занимает некоторое время — все работает нормально (по крайней мере, результаты в порядке).

Что меня беспокоит, так это то, что через некоторое время мой графический интерфейс, кажется, не отвечает: например, мой ProcessBar то, что отображается во время вычислений, не будет отображаться, а в строке заголовка моего графического интерфейса пользователя текст «Кейн Рюкмелдунг» добавлено (что означает что-то вроде занято, сбой и т. д. — извините, я не знаю правильный перевод, из-за которого мне трудно найти что-либо в Интернете по этому вопросу).

Есть ли возможность остановить это поведение?

Спасибо.

0

Решение

У вас есть два варианта. Более эффективным является помещение ваших вычислений в другой поток (или несколько потоков, в современных ПК очень мало одноядерных процессоров). Ответ Сильвера имеет несколько ссылок для вас.

Однако с потоками приходит множество связанных с потоками вещей, которые вы должны изучить и принять во внимание. Существует большой потенциал для тонких ошибок, если вы не знаете, что делаете. Поэтому я бы рекомендовал альтернативный подход в качестве первого шага, однопоточный. В качестве бонуса это значительно облегчит переход к многопоточному решению.

  1. Создайте простой подкласс QObject. В этот объект QObject поместите состояние вашего вычисления в качестве переменных-членов.

  2. Запишите метод slot в вышеприведенный класс, который выполняет небольшую часть вычисления и затем возвращает. Это должно сделать это самое большее около 50 мс для хорошего пользовательского опыта. Вы можете просто использовать фиксированное количество итераций в цикле или использовать QElapsedTimer измерять время или что-то еще. А затем при повторном вызове метод должен продолжить вычисление еще 50 мс. Когда вычисление завершено, метод может, например, подать сигнал с результатами.

  3. Добавить QTimer с интервалом 0. Подключите тайм-аут к методу слота, описанному выше. Интервал 0 здесь фактически означает, что Qt будет вызывать метод так часто, как может. Вы хотите этого, потому что вы хотите, чтобы вычисление закончилось как можно быстрее, конечно. Однако, поскольку метод возвращается очень скоро, Qt может выполнить другие действия (обновить GUI и т. Д.) Перед повторным вызовом вашего метода.

Как только это сработает, в одном потоке вы сможете научиться выполнять потоки Qt и переместить рабочий объект для работы в другом потоке, что потенциально повысит производительность. Кроме того, у вас будет однопоточная базовая версия для сравнения в случае возникновения проблем с многопоточностью.

1

Другие решения

Вы должны передать свои дорогостоящие и длительные вычисления из потока GUI в рабочий поток, чтобы предотвратить зависание вашего GUI.

Qt-документация: Threading Basics

Хорошее объяснение использования QThread мне показалось полезным: How To Really, Truly Use QThreads

Сам графический интерфейс не может быть изменен из рабочего потока. Ты должен notify Ваш основной поток об изменении данных и обновите свой графический интерфейс оттуда.

2

По вопросам рекламы [email protected]