2013-04-22 14 views
5

私はQtでUIアプリケーションを使用しています。何千もの結果を返す大規模なSQLクエリを実行する関数がいくつかあります。Qtプログラムがハングする(応答しない)関数が終了してから再び動作するまで

このクエリを実行するボタンをクリックすると、UIウィンドウがただちに「応答しません」に変わりますが、コンソール出力からすべてが実際にバックグラウンドで実行されていることがわかります。関数が終了すると、データが期待通りに表示され、UIが再び応答して完全に機能します。

これは、この機能が多数の結果のために何千回もループしていることが原因であることがわかりましたが、私は、検索が進むにつれて進行するローディングバーを入れてもらいたいと考えていました。プログラムのように見えるようにウィンドウをロックするだけでクラッシュしました。 AFAIK私はメモリリークを持っていないので、誰もが何か提案を持っていますか?

ああも、私がクリックしたときに、そのボタンのタスクマネージャにのみ、このプロセスに使用されているメモリのMBのカップルとプロセッサは、アプリケーションでは

+8

あなたは_threading_について読んでください。 –

+0

'threading'であなた自身を知ってください... –

+2

また、あなたの機能を実行している間は、GUIを駆動するイベントループ全体が実行されないので、プログレスバーを表示するだけでは役に立ちません。 Qtを使用すると、時間がかかることがある作業を行うときにワーカースレッドを開始するのは簡単です。ワーカースレッドは、進捗バーを更新するための信号をGUIに簡単に送信することができます。 –

答えて

3

のいずれかを限界いっぱいまでされるものではない示しているので、そのないメモリネギを考えイムUIイベント、メッセージ、それらを呼びたいものを処理する責任があるスレッドが1つあります。ボタンクリックイベントがあるとします。コールバック関数から戻らない限り、他のUIイベント(再描画、更新など)がトリガされず、UIが応答しなくなります。

これを軽減するには、時間のかかるタスクを別のスレッドで実行し、完了したらそれに応じてUIを更新することを検討する必要があります。タスクが処理されている間にUIをブロックする必要がある場合は、コントロールを無効にしたり、ポップアッププログレスバーを表示したりすることができますが、「応答しない」問題を避けるためにUIスレッドを比較的空にしておきます。

+0

ありがとうございましたスレッドを見て、私はこれはコードのいくつかの巨大な書き換えになるだろうと仮定かなり容易に組み込むことができますか? – AngryDuck

+0

@AngryDuck、[Threading Basics](http://qt-project.org/doc/qt-4.8/thread-basics.html) – Paul

+0

私はスレッドのプリンシパルを取得しますが、ドキュメントはとても不完全です。それを組み込むために – AngryDuck

5

スレッドを使用するより簡単な解決策は、QCoreApplication::processEvents()を使用することです。あなたのコードは次のようなものである場合:1つのSQLクエリまたは1 doSomethingWithResult(場合

void slowFunction() 
{ 
    lostOfResults = makeSqlQuery(...); // quite fast 
    for (r in lostOfResults) 
     doSomethingWithResult(r); // one call is quite fast 
} 

)あまりにも多くの時間を取ることはありません、あなたはこのようなQCoreApplication ::のprocessEventsを(使用して保留中のイベント)を処理することができます

void slowFunction() 
{ 
    lostOfResults = makeSqlQuery(...); 
    for (r in lostOfResults) 
    { 
     doSomethingWithResult(r); 
     QCoreApplication::processEvents(); 
    } 
} 

GUIイベントが処理され、プログラムがフリーズしません。しかし、SQLクエリだけで時間(数秒)がかかる場合、これは役に立ちません。次に、別のスレッドを検討する必要があります。

関連する問題