Некоторое время назад я написал небольшой класс RAII, чтобы обернуть методы setOverrideCursor()
и restoreOverrideCursor()
в QApplication
.Создание этого класса установит курсор, а деструктор восстановит его.Поскольку курсор переопределения является стеком, это работало довольно хорошо, например:
{
CursorSentry sentry;
// code that takes some time to process
}
Позже я обнаружил, что в некоторых случаях для обработки кода иногда требуется заметное время (скажем, болееполсекунды) и в других случаях это будет почти мгновенно (из-за кеширования).Трудно определить заранее, какой случай произойдет, поэтому он все еще всегда устанавливает курсор ожидания, создавая объект CursorSentry
.Но это может вызвать неприятное «мерцание», когда курсор быстро превратится из ждущего курсора в обычный курсор.
Поэтому я подумал, что буду умен, и добавил отдельный поток для управления переопределением курсора.Теперь, когда создается CursorSentry
, он отправляет запрос потоку курсора на переход в состояние ожидания.Когда он уничтожен, он сообщает потоку вернуться в нормальное состояние.Если CursorSentry
живет дольше некоторого промежутка времени (50 миллисекунд), то изменение курсора обрабатывается и устанавливается курсор переопределения.В противном случае запрос на изменение отбрасывается.
Проблема в том, что поток курсора не может технически изменить курсор, потому что это не поток GUI.В большинстве случаев это действительно работает, но иногда, если мне действительно не повезло, вызов для изменения курсора происходит, когда поток GUI смешивается с некоторыми другими вызовами X11, и все приложение блокируется.Обычно это происходит только в том случае, если поток GUI заканчивает обработку почти в тот самый момент, когда поток курсора решает установить курсор переопределения.
Итак, кто-нибудь знает безопасный способ установки курсора переопределения из не-GUIнить.Имейте в виду, что большую часть времени поток GUI будет занят обработкой чего-либо (вот почему курсор ожидания необходим, в конце концов), поэтому я не могу просто поместить событие в очередь потока GUI, потому что он выиграл 'не будет обработано, пока не станет слишком поздно.Кроме того, нецелесообразно переносить обработку, о которой я говорю, в отдельный поток, потому что это происходит во время события рисования, и оно должно выполнять работу с графическим интерфейсом по завершении (выяснение того, что рисовать).
Любые другие идеи по добавлению задержки для установки курсора переопределения тоже подойдут.