Как узнать, когда PyQt-приложение простаивает?
-
21-08-2019 - |
Вопрос
Я хотел бы знать, когда мое приложение простаивает, чтобы я мог предварительно загрузить некоторый контент.Есть ли событие или что-то подобное, реализованное в PyQt?
(Я также мог бы сделать это с помощью потоков, но это кажется слишком сложным.)
Решение
У вас есть как минимум два разных варианта: вы можете использовать поток или таймер.Класс QThread в Qt предоставляет свойство приоритета, которое вы можете установить, чтобы он обрабатывался только тогда, когда другие потоки не запущены, включая поток графического интерфейса.Другой вариант — таймер одиночного выстрела.QTimer с тайм-аутом 0 миллисекунд помещает событие в конец очереди событий, чтобы все события и синхронные функции, уже активные или запланированные, были обработаны в первую очередь.
В коде эти два параметра будут выглядеть следующим образом:
// (1) use idle thread processing
MyQThreadSubclass idleThread;
idleThread.run(QThread::IdlePriority);
// (2) use QTimer::singleShot
QTimer::singleShot(0, receiver, SLOT(doIdleProcessingChunk));
Если вы используете однократный QTimer, будьте осторожны с объемом обработки, поскольку вы все равно можете заблокировать графический интерфейс.Вероятно, вам захочется разбить его на куски, чтобы графический интерфейс не начал лагать:
// slot
void doIdleProcessingChunk() {
/* ... main processing here ... */
if (chunksRemain())
QTimer::singleShot(0, receiver, SLOT(doIdleProcessingChunk));
}
Очевидно, что приведенное выше является синтаксисом C++, но для ответа относительно PyQt используйте таймер одиночного выстрела.В Python глобальная блокировка интерпретатора по сути сделает большую часть вашего параллелизма бессмысленной, если вызываемая реализация выполняется внутри Python.
У вас также есть выбор: использовать потоки Python или потоки Qt, оба хороши по разным причинам.
Другие советы
Посмотри на QAbstractEventDispatcher. Но ...Я все же предлагаю использовать нить.Причины:
- Он будет портативным
- Если вы допустите ошибку в своем коде, цикл событий будет нарушен -> Ваше приложение может зависнуть, внезапно выйти и т. д.
- Во время предварительной загрузки ваше приложение зависает.Никакие события не будут обрабатываться, если вы не сможете предварительно загрузить контент по одному, все они очень маленькие, загрузка занимает всего несколько миллисекунд и т. д.
Используйте поток и отправьте сигнал в основной поток, когда контент будет готов.Это намного проще.