Qt: установка переопределения курсора из потока без графического интерфейса - PullRequest
3 голосов
/ 18 июля 2011

Некоторое время назад я написал небольшой класс RAII, чтобы обернуть методы setOverrideCursor() и restoreOverrideCursor() в QApplication.Создание этого класса установит курсор, а деструктор восстановит его.Поскольку курсор переопределения является стеком, это работало довольно хорошо, например:

{
   CursorSentry sentry;
   // code that takes some time to process
}

Позже я обнаружил, что в некоторых случаях для обработки кода иногда требуется заметное время (скажем, болееполсекунды) и в других случаях это будет почти мгновенно (из-за кеширования).Трудно определить заранее, какой случай произойдет, поэтому он все еще всегда устанавливает курсор ожидания, создавая объект CursorSentry.Но это может вызвать неприятное «мерцание», когда курсор быстро превратится из ждущего курсора в обычный курсор.

Поэтому я подумал, что буду умен, и добавил отдельный поток для управления переопределением курсора.Теперь, когда создается CursorSentry, он отправляет запрос потоку курсора на переход в состояние ожидания.Когда он уничтожен, он сообщает потоку вернуться в нормальное состояние.Если CursorSentry живет дольше некоторого промежутка времени (50 миллисекунд), то изменение курсора обрабатывается и устанавливается курсор переопределения.В противном случае запрос на изменение отбрасывается.

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

Итак, кто-нибудь знает безопасный способ установки курсора переопределения из не-GUIнить.Имейте в виду, что большую часть времени поток GUI будет занят обработкой чего-либо (вот почему курсор ожидания необходим, в конце концов), поэтому я не могу просто поместить событие в очередь потока GUI, потому что он выиграл 'не будет обработано, пока не станет слишком поздно.Кроме того, нецелесообразно переносить обработку, о которой я говорю, в отдельный поток, потому что это происходит во время события рисования, и оно должно выполнять работу с графическим интерфейсом по завершении (выяснение того, что рисовать).

Любые другие идеи по добавлению задержки для установки курсора переопределения тоже подойдут.

1 Ответ

0 голосов
/ 18 мая 2012

Я не думаю, что есть какой-то другой путь, кроме соединения Signal-Slot, идущего к потоку GUI с последующим вызовом qApp->processEvents(), но, как вы сказали, это, вероятно, не будет работать хорошо, когда поток GUI связан .

Документация для QCoreApplication :: processEvents также имеет некоторые рекомендуемые применения с обработкой длинных событий:

Эта функция перегружает processEvents (). Процессы, ожидающие события для вызывающий поток в течение максимального времени миллисекунд или пока нет больше события для обработки, в зависимости от того, что короче.

Вы можете вызвать эту функцию иногда, когда ваша программа занята выполнением длительной операции (например, копирование файла).

Вызов этой функции обрабатывает события только для вызывающая нить.

Если возможно, прервите длинные вызовы в событии рисования и периодически проверяйте его, чтобы увидеть, сколько времени это заняло. И в любой из этих проверок он должен установить курсор переопределения затем из потока GUI.

Часто QProgressBar может иметь большое значение для передачи той же информации пользователю.

Другой вариант, который может немного помочь, - это рендеринг вне потока GUI в буфер QImage, а затем отправка его в GUI, когда это будет сделано.

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