#cpp #qt #многопоточность
Привет всем! накидал маленький рабочий пример за 5 минут, но возник вопрос, как правильно закрыть поток? При старте создаётся новый поток, а старый сохраняется... Возможно, что то не учёл или сделал не так. Вот исходники: main.cpp #include "mainwindow.h" #includeint 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
Ответы
Ответ 1
В приведенном коде не испускается сигнал 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); }
Комментариев нет:
Отправить комментарий