6

今のところ、さまざまなソースからデータを収集するためにいくつかのスレッド(5〜10など)を開始するアプリケーションがあります。
これらはメインのGUIスレッドから分離されているため、GUIの速度が低下することはなく、バックグラウンドスレッドが機能している間も機能し続けることができます。すべて素晴らしい。
しかし今は、メインGUIのQTableViewに結果を表示できるようにしたいと思っています。データはそれらの文字列割り当てであり、QTableViewで最大100,000行になると想定される10,000〜100,000の結果を持つことができます。

私の質問は、メインGUIのテーブルをスレッドから更新して、更新中にTHGUIが遅くなったりアイドル状態になったりしないようにするための最良の方法は何ですか。

4

2 に答える 2

8

これは私がそれを行う方法です:

データの新しいバッチの準備が整うたびに発行されるワーカー スレッドにシグナルを追加します。Qt::QueuedConnection を使用して、このシグナルをメイン GUI スレッドで定義されたスロットに接続します。このスロットは、処理されたデータをワーカー スレッドから収集し、テーブルのモデルに挿入する必要があります。モデルは当然 GUI スレッドにもあるはずです。

更新 1

より詳細な説明。スレッドはすでにダウンしているので、あとはスレッドを少し拡張するだけです。例:

// NOTE:
// In this example I'm assuming that the thread continues to work after
// preparing first batch of data. One thread can prepare multiple batches
// over time. If that's not the case for you then you can probably
// safely ignore mutex stuff and intermediary tmp variables.
class MyWorker : public QThread
{
    // ...
    public:
        void run()
        {
            while (bWork)
            {
                QList<MyData> myData;
                // Populate 'myData' variable with your data.
                // ...

                // Now, store myData in more persistent buffer and emit the
                // ready signal.
                dataBatchMutex.lock();
                dataBatch.append(myData);
                dataBatchMutex.unlock();
                emit dataBatchReady();
            }
        }

        QList<MyData> popLastBatch()
        {
            QMutexLocker l(&dataBatchMutex);
            QList<MyData> tmp = dataBatch;
            dataBatch.clear();
            return tmp;
        }

    signals:
        void dataBatchReady();

    private:
        QMutex dataBatchMutex;
        QList<MyData> dataBatch;
};

ワーカースレッドがあります。GUIスレッドについて:

  1. ワーカー スレッド オブジェクトを作成します。
  2. dataBatchReady()信号を GUI スレッドのスロットに接続します。使用することを忘れないでくださいQt::QueuedConnection
  3. スレッドを開始します。
  4. そのスロットが実行されると、どのワーカー スレッドに新しいデータがあるかを把握する必要があります。それらをすべてポップすることも (あまり効率的ではありません)、ワーカーにメソッドを追加して、dataBatchフィールドが空でないかどうかを調べることもできます。また、どのスレッドがシグナルを発したかを把握する別の方法を考案することもできます。それはあなた次第です。
  5. スレッドを見つけたら、そのスレッドで を呼び出し、popLastBatch()返されたリストをモデルに追加します。残りはモデルが処理します。それでもパフォーマンスの問題がある場合は、tHand の回答を参照してください。

注:コードをテストしていないため、明らかなエラーが含まれている可能性があります。ただし、アイデアは得られるはずです。

于 2012-11-28T12:59:39.310 に答える
1

パフォーマンスの問題は、各行が追加されるときにコントロールによって実行されるアクションに関連している可能性があります。

たとえば、次を参照してください 。QTableViewは非常に遅い(3000行のみの場合でも)

于 2012-11-28T13:32:40.200 に答える