У меня есть приложение, которое сейчас запускает несколько потоков (например, 5 — 10) для сбора данных из разных источников.
Они отделены от основного потока GUI, поэтому я не чувствую никакой медлительности в GUI и могу продолжать работать, пока работают фоновые потоки. все здорово .
Но теперь мне нравится отображать результаты в QTableView в моем основном графическом интерфейсе. данные представляют собой их строки, и они могут иметь от 10 000 до 100 000 результатов, которые должны составлять до 100 000 строк в QTableView.
Мой вопрос заключается в том, каков наилучший способ обновления таблицы в главном графическом интерфейсе из потоков, чтобы при обновлении графический интерфейс TH не работал медленно или бездействовал.
Вот как я бы это сделал:
Добавьте сигнал к рабочим потокам, который генерируется каждый раз, когда новый пакет данных готов. Подключите этот сигнал к слоту, определенному в основном потоке графического интерфейса, используя Qt :: QueuedConnection. Этот слот должен собирать обработанные данные из рабочих потоков и вставлять их в модель таблицы. Модель должна быть естественно также в потоке GUI.
Более подробное объяснение. У вас уже есть нити, поэтому вам нужно лишь немного их расширить. Пример:
// 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:
dataBatchReady()
Сигнал к слоту в потоке GUI. Не забудьте использовать Qt::QueuedConnection
,dataBatch
поле не пустое Вы также можете придумать другой способ выяснить, какой поток испустил сигнал — это решать вам.popLastBatch()
в этом потоке и добавьте возвращенный список к модели. Модель позаботится об остальном. Если у вас все еще есть проблемы с производительностью, обратитесь к ответу tHand.Замечания: Я не тестировал код, поэтому он может содержать некоторые очевидные ошибки. Вы должны понять, хотя.
Ваша проблема с производительностью может быть связана с действиями, выполняемыми элементом управления при добавлении каждой строки.
Например, см .:
QTableView работает очень медленно (даже для 3000 строк)