前一段時間我寫了一個小的RAII類來包裝QApplication
上的setOverrideCursor()
和restoreOverrideCursor()
方法。構造這個類將設置遊標,並且析構函數將恢復它。由於覆蓋光標是一個堆棧,這個做得很不錯,如:Qt:從非GUI線程設置超馳光標
{
CursorSentry sentry;
// code that takes some time to process
}
後來,我發現,在某些情況下,處理代碼有時會採取感知的時間來處理(比如超過半秒),而其他時間則幾乎是瞬時的(因爲緩存)。事先很難確定哪種情況會發生,因此它總是通過創建一個CursorSentry
對象來設置等待光標。但是這可能會導致一個令人不快的「閃爍」,光標會從等待光標快速轉到正常光標。
所以我想我會很聰明,我添加了一個單獨的線程來管理光標覆蓋。現在,當生成CursorSentry
時,它將請求遊標線程進入等待狀態。當它被銷燬時,它會告訴線程返回到正常狀態。如果CursorSentry
的壽命超過一段時間(50毫秒),則處理光標更改並設置超馳光標。否則,更改請求將被丟棄。
問題是,遊標線程無法在技術上更改遊標,因爲它不是GUI線程。在大多數情況下,它確實發生了工作,但有時候,如果我真的不幸,改變遊標的調用發生在GUI線程與其他X11調用混合在一起時,並且整個應用程序被鎖定。這通常只發生在GUI線程幾乎在遊標線程決定設置覆蓋遊標的時刻完成處理。
那麼,有沒有人知道從非GUI線程設置覆蓋光標的安全方法。請記住,大多數情況下,GUI線程將忙於處理東西(這就是爲什麼需要等待遊標),所以我不能只將一個事件放入GUI線程隊列中,因爲它贏得了'直到爲時已晚。而且,將我正在討論的處理移動到單獨的線程是不切實際的,因爲這是在繪製事件期間發生的,並且在完成GUI時需要執行GUI工作(弄清楚要繪製什麼)。
任何其他增加延遲設置倍率光標的想法都是很好的。