Страницы

Поиск по вопросам

четверг, 2 мая 2019 г.

QThread Потоки ( как правильно закрыть поток )

Привет всем! накидал маленький рабочий пример за 5 минут, но возник вопрос, как правильно закрыть поток? При старте создаётся новый поток, а старый сохраняется... Возможно, что то не учёл или сделал не так. Вот исходники:
main.cpp
#include "mainwindow.h" #include
int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show();
return a.exec(); }
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include #include
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); connect(this->ui->pushButton_start, SIGNAL(clicked()), this, SLOT(startGUI())); connect(this->ui->pushButton_stop, SIGNAL(clicked()), this, SLOT(stopGUI())); }
MainWindow::~MainWindow() { delete ui; }
void MainWindow::startGUI() {
// Создание потока QThread* thread = new QThread; Worker* worker = new Worker();
// Передаем права владения "рабочим" классом, классу QThread. worker->moveToThread(thread);
//connect(worker, SIGNAL(sendBool(bool)), this, SLOT(stopGUI(bool)));
// Связываем сигнал об ошибки со слотом обработки ошибок(не показан). //connect(worker, SIGNAL(error(QString)), this, SLOT(errorHandler(QString)));
// Соединяем сигнал started потока, со слотом process "рабочего" класса, т.е. начинается выполнение нужной работы. connect(thread, SIGNAL(started()), worker, SLOT(process()));
// Отображаем в главном потоке Gui, значения из вторичного потока connect(worker, SIGNAL(sendNumber(int)), this, SLOT(LineEditUi(int)));
// Оповещаем поток, что нужно остановиться connect(this, SIGNAL(sendNumberBoolStop(bool)), worker, SLOT(reciveBoolStop(bool)), Qt::DirectConnection);
// По завершению выходим из потока, и удаляем рабочий класс connect(worker, SIGNAL(finished()), thread, SLOT(quit())); connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
// Удаляем поток, после выполнения операции connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start(); }
void MainWindow::LineEditUi(int number) { ui->lineEdit->setText(QString::number(number)); }
void MainWindow::stopGUI() { Stop = true; qDebug() << Stop; sendNumberBoolStop(Stop); qDebug() << "sendMumberBoolStop = " << Stop; }
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H
#include #include "worker.h"
namespace Ui { class MainWindow; }
class MainWindow : public QMainWindow { Q_OBJECT
public: explicit MainWindow(QWidget *parent = 0); ~MainWindow();
bool Stop;
public slots: void startGUI();
void stopGUI(); void LineEditUi(int number);
signals: void sendNumberBoolStop(bool);
private: Ui::MainWindow *ui; };
#endif // MAINWINDOW_H
worker.cpp
#include "worker.h" #include
Worker::Worker(QObject *parent) : QObject(parent) { Stop = false; temp = 0; }
Worker::~Worker() { qDebug() << "destruction Thread"; }
void Worker::process() { Stop = false; if(!Stop == true) { for (temp; temp <= 1000; temp++) { if(!Stop == true) { emit(sendNumber(temp)); //ui->lineEdit->setText(QString::number(temp)); //QCoreApplication::processEvents(); qDebug() << temp; } else { return; } } } }
void Worker::reciveBoolStop(bool Numb) { Stop = Numb; qDebug() << "reciveBoolStop = " << Stop; }
worker.h
#ifndef WORKER_H #define WORKER_H
#include
class Worker : public QObject { Q_OBJECT public: //Worker(); //virtual ~Worker(); explicit Worker(QObject *parent = 0); ~Worker();
bool Stop; int temp;
signals: void finished(); //void error(QString err);
void sendNumber(int);
public slots: void process();
void reciveBoolStop(bool Numb); };
#endif // WORKER_H
mainwindow.ui
MainWindow 0 0 395 165 MainWindow Start Stop 0 0 395 21 TopToolBarArea false


Ответ

В приведенном коде не испускается сигнал Worker::finished, следовательно поток не понимает, что ему нужно остановиться. Испустить сигнал нужно на выходе из функции Worker::process
Добавлю, что для задачи единоразово запустить какой-то процесс в отдельном потоке лучше подойдет QtConcurrent::run
void MainWindow::startGUI() { Worker* worker = new Worker();
// Отображаем в главном потоке Gui, значения из вторичного потока connect(worker, SIGNAL(sendNumber(int)), this, SLOT(LineEditUi(int)));
// Оповещаем поток, что нужно остановиться connect(this, SIGNAL(sendNumberBoolStop(bool)), worker, SLOT(reciveBoolStop(bool)), Qt::DirectConnection);
//Запланируем удаление воркера после окончания расчета connect(worker,SIGNAL(finished()), worker,SLOT(deleteLater())); QtConcurrent::run(worker,&Worker::process); }

Комментариев нет:

Отправить комментарий