2011-07-18 5 views
3

少し前に、QApplicationsetOverrideCursor()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作業を行う必要があるからです。

オーバーライドカーソルの設定に遅延を追加する他のアイデアも良いでしょう。

答えて

0

qApp->processEvents()コールの後に続く、シグナルスロット接続以外の方法はありませんが、あなたが言ったように、これはおそらくGUIスレッドが繋がっているとうまくいかないでしょう。 QCoreApplication::processEventsため

の資料もいくつかは、長いイベント処理で使用法を推奨しています

この関数は(のprocessEventsをオーバーロード)。処理中のイベントが の保留中のイベントを処理します。処理するイベントが最大で255秒、またはそれ以上になるまでのいずれか短い方です。

プログラムがファイルをコピーしているなど、長い操作でビジー状態になっているときに、この機能を呼び出すことができます。

この関数を呼び出すと、 呼び出しスレッドのイベントだけが処理されます。

可能であれば、ペイントイベントで長時間の通話を切断し、定期的に通話時間を確認してください。そして、これらのチェックのいずれかで、GUIスレッドからオーバーライドカーソルを設定します。

多くの場合、QProgressBarは、同じ情報をユーザーに伝えるために長い道を行くことができます。

GUIスレッドの外側でQImageバッファにレンダリングし、それが完了した後にGUIにポストすることも、かなり役に立ちます。

関連する問題