QTimer для обработки большого массива

Я пытался использовать QThread в своем приложении для обработки больших данных. Это работает, но не идеально и приводит к сбою моего приложения в его текущей версии по ссылке. Я где-то читал (не могу найти ссылку), чтобы вместо этого использовать QTimer, сигнал и слоты.

То, что я хотел бы сделать, это иметь возможность перебирать:

connect(this, &UsersProcess::ProgressBarSetValue, this->progressBar, &QProgressBar::setValue);

...
int maxRows = this->listUsers->size();
for(auto iter = this->listUsers->begin(); iter != this->listUsers->end(); ++iter)
{
     row++;
     emit this->ProgressBarSetValue(row);
}

где сигнал ProgressBarSetValue обновляет значение QProgressBar. Что я не уверен, что делать, так это поместить его в QTimer, чтобы он не делал MainWindow непригодным для использования до тех пор, пока цикл не закончится.

Интересно, может ли кто-нибудь дать мне идею или статью о том, как это сделать. Или если есть другие альтернативы без использования QThread.


person adviner    schedule 29.12.2015    source источник
comment
Возможный дубликат панели выполнения QT, показывающей состояние функции   -  person user2672165    schedule 29.12.2015


Ответы (1)


Посмотрите на библиотеку QtConcurrent. QtConcurrent::run может вам помочь.

Пример. В userprocess.h:

class UserProcess : public QMainWindow
{
    Q_OBJECT

public:
..............
    void setValue(int Value);

signals:
    void ProgreeBarSetValue(int Value);

private:
    Ui::UserProcess *ui;
    QStringList _data;
};

В .cpp вы определяете эту функцию:

void doWork(UserProcess* process, const QStringList &list)
{
    static int row = 0;
    for(auto iter = list.begin(); iter != list.end(); ++iter)
    {
        ++row;
        process->setValue(row);
        QThread::msleep(1); //just slows up this function
    }
}

Затем вы устанавливаете соединение с флагом Qt:QueuedConnection:

connect(this, &UserProcess::ProgreeBarSetValue, ui->progressBar, &QProgressBar::setValue, Qt::QueuedConnection);

Добавьте случайные данные в наш список

for(int i = 0; i < 1000; ++i)
        _data.append(QString::number(i));

ui->progressBar->setMaximum(1000);

И это

void UserProcess::setValue(int Value)
{
    emit ProgreeBarSetValue(Value);
}

Запускаем нашу жесткую функцию

QtConcurrent::run(doWork, this, _data);

Также не забудьте добавить это в файл .pro

QT +=  concurrent
person Evgeny    schedule 29.12.2015