6

我有一个应用程序,现在启动几个线程(如 5-10)来收集来自不同来源的数据。
它们与主 GUI 线程分开,所以我不会感觉到 GUI 有任何缓慢,而且我可以在后台线程工作时继续工作。一切都很好。
但现在我希望能够在我的主 GUI 中的 QTableView 中显示结果。数据是分配给它们的字符串,它可以有 10,000 到 100,000 个结果,这些结果应该在 QTableView 中多达 100,000 行。

我的问题是从线程更新主 GUI 中的表的最佳方法是什么,以便 TH GUI 在更新时不会变慢或空闲。

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 回答