Привет всем! накидал маленький рабочий пример за 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
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
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
Ответ
В приведенном коде не испускается сигнал 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);
}
Комментариев нет:
Отправить комментарий