Best QTableView Update Strategy with Real-Time Data from Different Streams

I have an application that currently runs several threads (e.g. 5-10) to collect data from another source.
They are separate from the main GUI thread, so I don’t feel slowness in the GUI, and I can continue to work while the background threads are running. all perfectly.
But now I like to show the results in QTableView in the main GUI. the data is a row of them and can have from 10,000 to 100,000 results, which should be up to 100,000 rows in a QTableView.

My question is the best way to update a table in the main GUI from threads, so TH GUI will not be slow or inactive when updating.

+4
source share
2 answers

Here's how I do it:

Add a signal to the workflows that are emitted each time a new batch of data is ready. Connect this signal to the slot defined in the main graphics stream using Qt :: QueuedConnection. This slot should collect processed data from workflows and insert them into the table. The model should also appear naturally in the GUI thread.

Update 1

More detailed explanation. You already have threads, so all you have to do is expand them a bit. Example:

// 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 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; }; 

We have a workflow. Now about the GUI thread:

  • Create your workflow objects.
  • Connect the dataBatchReady() signal to the slot in the GUI stream. Remember to use Qt::QueuedConnection .
  • Run threads.
  • When this slot runs, you need to find out which workflow contains the new data. You can put them all (not very efficiently), or you can add an additional method to the worker to find out if the dataBatch field dataBatch not empty. You can also come up with another way to find out which thread emitted the signal - what you need to find out.
  • When you popLastBatch() out the stream, just call popLastBatch() on that stream and add the returned list to the model. The model takes care of the rest. If you still have performance issues, check out tHand's request.

Note. I have not tested the code so that it may contain some obvious errors. You must understand this idea.

+6
source

Your performance problem may be related to the actions the control takes as each line is added.

For example, see QTableView extremely slow (even for 3000 rows)

0
source

All Articles