少し前に、QApplication
にsetOverrideCursor()
とrestoreOverrideCursor()
メソッドをラップするための少しのRAIIクラスを作成しました。このクラスを作成するとカーソルが設定され、デストラクタはそれを復元します。私はいくつかのケースでは、処理コードは時々(処理するために、知覚時間がかかる半数以上を言うことがわかった、後でQt:GUI以外のスレッドからオーバーライドカーソルを設定する
{
CursorSentry sentry;
// code that takes some time to process
}
:オーバーライド・カーソルがスタックがあるので、これはのように、非常によく働きました秒)とそれ以外の時間は(キャッシュのために)瞬時に近いでしょう。どのようなケースが発生するかは手前で判断するのが難しいため、CursorSentry
オブジェクトを作成して待機カーソルを設定します。しかし、これは、カーソルが待機カーソルから通常のカーソルに素早く切り替わる不快な「ちらつき」を引き起こす可能性があります。
私は賢いと思い、カーソルオーバーライドを管理する別のスレッドを追加しました。今度は、CursorSentry
が作られると、カーソルスレッドに待ち状態に入る要求を出します。破棄されるとスレッドは通常の状態に戻るように指示します。 CursorSentry
が一定の時間(50ミリ秒)より長く続く場合、カーソルの変更が処理され、オーバーライドカーソルが設定されます。それ以外の場合は、変更要求は破棄されます。
カーソルスレッドは、GUIスレッドではないためカーソルを技術的に変更できないという問題があります。ほとんどの場合、うまくいきますが、私が本当に不運な場合は、GUIスレッドが他のX11呼び出しと混じり合ってアプリケーション全体がデッドロックすると、カーソルを変更する呼び出しが発生することがあります。これは通常、カーソルスレッドがオーバーライドカーソルを設定する直前にGUIスレッドが処理を終了した場合にのみ発生します。
したがって、非GUIスレッドからオーバーライドカーソルを設定する安全な方法を知っている人はいますか?ほとんどの場合、GUIスレッドは処理中のものを処理するためにビジー状態になります(なぜなら、待機カーソルが必要なのです)。そのため、GUIスレッドキューにイベントを入れることはできません。なぜなら、遅すぎるまで処理されません。また、私が話している処理を別のスレッドに移動することは実用的ではありません。なぜなら、これはペイントイベント中に起きているためであり、完了するとGUI作業を行う必要があるからです。
オーバーライドカーソルの設定に遅延を追加する他のアイデアも良いでしょう。