Как остановить бесконечный поток из нового диалогового окна

153
09 декабря 2021, 18:50

Запустил бесконечный поток из окна mainwindow. Создал диалоговое окно menu по нажатию на кнопку мне нужно остановить бесконечный поток. Но как это сделать? Не ясно мне. Ведь указатель на бесконечный поток остался в mainwindow.

Вот я создал поток в mainwindow:

QThread* pThread = new QThread; 
threadbalancerautomode->moveToThread(pThread); 
QObject::connect(pThread, SIGNAL(started()), threadbalancerautomode, SLOT(slotStartAutoMode())); 
pThread->start(); 

Останавливаю поток из mainwindow:

if(threadbalancerautomode) { 
    threadbalancerautomode->slotStopAutoMode(); 
}

создал диалоговое окно menu_1 dialog;

dialog.setModal(true); 
dialog.setWindowFlags(Qt::FramelessWindowHint); 
dialog.exec(); 

и как из него остановить поток не знаю?

Answer 1

У вашего бесконечного потока где-то внутри есть цикл, а у этого цикла есть условие завершения. Проверяйте в этом условии, что переменная типа std::atomic<bool> все еще истина, и если она стала ложной - выходите из цикла. Чтобы все работало и было чисто написано, желательно передать переменную в поток по константной ссылке.

Answer 2
class MainWindow : public QMainWindow {
    Q_OBJECT
    <какой-то метод, или конструктор>() {
        // создаем поток
        _thread = new MyThread();
        ...
    }
public slots:    
    void showDialog() {
        QDialog dialog = ...;
        if(dialog.exec() == <Ok>) {
            _thread->stop();
            // Идем дальше...
        }
    }
}

При этом поток может выглядеть, например так:

class MyThread : public QThread {
    Q_OBJECT 
    ...
public slots:
    void stop() {
        QMutexLocker locker(&_mutex);
        _active = false;
    }
protected: 
    void run() override {
        QMutexLocker locker(&_mutex);
        _active = true;
        locker.unlock();
        while(true) {
            locker.relock();
            if( !_active )
                break;
            locker.unlock();
            // делаем что-то бесконечное
        } 
    }
    ...
private:
    bool _active;
    QMutex _mutex;
}

Дополнение Если вы хотите остановить поток из диалога не закрывая его, то надо воспользоваться сигналами/слотами. Например, добавьте в ваш диалог сигнал, например, выбора пункта меню:

class MyDialog : public QDialog {
signals:
    void menuItemSelected(/*Здесь могли бы быть ваши аргументы*/);
}

Далее в основном окне, до вызова exec() у диалога, создаем коннект (в каком-либо методе главного окна приложения, mainwindow):

connect(&dialog, &MyDialog::menuItemSelected, this, [=](/*Аргументы из сигнала*/) {
    // Останавливаем поток
    if( pThread != nullptr ) {
        pThread->stop();
    }
});
// а теперь запускаем наш диалог
dialog.exec();
READ ALSO
Как сравнить значения из вектора структур

Как сравнить значения из вектора структур

Всем еще раз здрасте)Сейчас попробую более дитально описать проблему

206
Вычисление суммы ряда

Вычисление суммы ряда

мне нужно сделать код так, чтобы получился пример под цифрой 2 но код я смог сделать только так, что у меня получается пример под цифрой 1 Как...

239
Сортировка массива объектов по string полю

Сортировка массива объектов по string полю

Есть такой класс администратора

70