Работа с QTimer, QThread и ProgressBar

161
02 декабря 2018, 21:30

Хочется выполнить вычисления в отдельном от Ui потоке без всяких сигналов. Метод, выполняющий вычисления — это приватный слот главного окна. По окончанию вычислений данные вываливаются в объект OutputData, который является полем главного окна. Поток, в котором выполняются вычисления — это тоже поле главного окна.

Конструктор главного окна, где создаётся поток и связывается начала вычислений и старт потока:

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow) {
ui->setupUi(this);
calculation = new QThread(this);
settings.setToDefault();
outputData.setToDefault();
calculationDone = false;
connect(calculation, SIGNAL(started()), this, SLOT(calculate()));
ui->results_display->setText("Загрузите <b>параметры</b> и начинайте расчёты!");
}

Метод нажатия на кнопку, запускающий поток и модальное окно с ProgressBar:

void MainWindow::on_calculate_button_clicked() {
ui->results_display->clear();
ui->results_display2->clear();
calculation->start();
///TODO QProgressDialog
ProgressDialog progressDialog(&outputData, this);
progressDialog.setModal(true);
progressDialog.exec();
if (progressDialog.result() == QDialog::Rejected) {
    calculation->terminate();
    QMessageBox::critical(this, "Результат", "Расчёт был остановлен!");
} else {
    if (progressDialog.result() == QDialog::Accepted) {
        calculation->quit();
        QMessageBox::about(this, "Результат", "Готово!");
        }
    }
}

Конструктор модального окна с ProgressBar, где происходит настройка ProgressBar, создание таймера и его связь с обновлением ProgressBar:

ProgressDialog::ProgressDialog(OutputData *outputData, QWidget *parent) :
QDialog(parent),
ui(new Ui::ProgressDialog) {
ui->setupUi(this);
data = outputData;
ui->quantity_label->setText("0");
ui->progressBar->setMinimum(0);
ui->progressBar->setMaximum(static_cast<int>(data->outputSettings.aircraftQuantity));
timer = new QTimer(this);
timer->setSingleShot(false);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(50);
}

Метод, обновляющий информацию ProgressBar'a:

void ProgressDialog::update() {
unsigned long aircraftsDone = data->results.size() + data->unprocessedAircrafts.size();
ui->progressBar->setValue(static_cast<int>(aircraftsDone));
ui->aircraftQunatityDone_label->setText(QString::number(aircraftsDone));
ui->progressBar->repaint();
if (aircraftsDone == data->outputSettings.aircraftQuantity) {
    accept();
   }
}

На данный момент вычисления происходят, однако информация о прогрессе никак не отрисовывается и не обновляется.

Answer 1

Как и советовали выше, в классе главного окна создал поле потока, в конструкторе окна задается поток и через connect сделана связь метода вычислений и старта потока:

connect(calculationThread, SIGNAL(started()), outputData, SLOT(calculate()));
READ ALSO
Работа с массивом строк

Работа с массивом строк

У меня есть массив строк:

182
C++ WinApi отделить UI View от кода

C++ WinApi отделить UI View от кода

Можно ли сделать что-то похожее на XAML в C# (WPF)? Отделить UI от кода?

177
Qt, аналог fread()

Qt, аналог fread()

Мне необходимо считать из файла данные в двоичном виде - сначала несколько int, потом uint8_t, затем еще кое-что

137
ошибка при открытии терминала в netbeans: unable to start pty process

ошибка при открытии терминала в netbeans: unable to start pty process

Раньше в netbeans терминал Cygwin работал даже без открытия java проекта, но теперь после обновления пишет сообщение "unable to start pty process": Прошу тока не предлагать...

237