2012-01-01 7 views
0

の画像をQLabelに表示するプログラムを作成中です。イメージはサーバーから送信されます。まず、サーバーからの接続とデータの受信を担当するスレッドがあります。データが受信されると、ソケットスレッドは、 updateImage(Imagedata)スロットに接続された信号gotNewData(Imagedata)を送信します。 updateImage(Imagedata)スロットでは、サーバーから取得した画像データをQImageに変換し、QPixmapを作成してQLabelに設定します。私の問題は、処理中にupdateImage(Imagedata)機能は、ソケットは、新しい画像で他のパッケージを取得し、QWidgetに何度も何度も送信することです。以前のシグナル呼び出しによって呼び出された関数updateImage(Imagedata)が既に終了しているかどうかは、ソケットスレッドが気にしないので論理的です。私の質問です:いくつかのテクニックは、どのようにQWidgetupdateImage(Imagedata)機能と私のソケットスレッドを同期させることができますか?QLabelをサーバからの画像データで頻繁に更新する

答えて

0

ありがとうございます。問題は、古いものがまだ処理されている間に新しい画像が受信された場合に達成したいことです。新しいものをスキップして最後まで処理したい場合は、オブジェクトを送信する際にblockSignalsを呼び出すことをおすすめします。これは呼び出し側と呼び出し側の文字列を破棄しますが、qtはシグナルを受信するのをブロックすることはできません。 ラベルを含むウィジェットでプロキシQObjectを作成した後、moveToThread()を使ってネットワーキングスレッドに移動し、onにblockSignalsを使用することで、パフォーマンスに多大な影響を与えず、他のコミュニケーションネットワークと混同しないようにする変更このオブジェクト。当然のことながら、このオブジェクトは、送信される実際の信号と同じ署名の信号を必要とします。作成されたオブジェクトは、スレッドアフィニティが異なるが、論理的にはGUIウィジェットによって所有されたままであり、それによって削除されるべきである。

もう1つの方法は、オブジェクトにブール変数processingを作成し、データを処理する場合はtrueに設定します。 falseに戻す直前に、QCoreApplication::processEvents();と呼びます。これは、イベントキュー内のすべてのイベントを処理します。あなたのスロットでは、processing vaiableが設定されているかどうかをチェックし、そうであれば何もしないでください。シンプルで粗末なソウルティションですが、うまくいきます。あなたのGUIスレッドでprocessEvents();(例えばそれ以上のラベルのような)を呼び出す他のイベントハンドラがある場合、ラベルの中にはデータの取得を止める(フリーズする)かもしれないことに注意してください。

Qt::BlockingQueuedConnectionを使用すると、処理が完了する前にネットワーキングスレッドが何かを受け取るのをブロックすることができますが、それはさまざまな理由から悪い考えです(それを同期すると、別のスレッドが必要になります)。

+0

ユーザーはGUIを使用できるはずですから、ソケットにソケットを挿入しました。私の場合、ユーザーが何らかのボタンを押すと、いくつかのコマンドがサーバーに送られます。私は他のソケット接続を使用してコマンドを送信します。だからこそ私は画像受信機ソケットをスレッドに入れ、プログラムとのユーザーのやりとりを妨げてはいけません。 –

+0

私は 'あなたがそれを同期させるのであれば、なぜ別のスレッドが必要なのでしょうか?'と言っていましたが、とにかく、最初の解決策はいい考えです。 –

関連する問題