2016-12-31 3 views
0

У меня есть следующий класс работника:Выхода QThread когда GUI приложения выходят

class MediaWorker : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit MediaWorker(QObject *parent = 0); 
    ~MediaWorker(); 

    void Exit(); 

signals: 
    void Finished(); 

public slots: 
    void OnExecuteProcess(); 
}; 

В MediaWorker.cpp

void MediaWorker::Exit() 
{ 
    emit Finished(); 
} 

void MediaWorker::OnExecuteProcess() 
{ 
    qDebug() << "Worker Thread: " << QThread::currentThreadId(); 
} 

В моей MainWindow я делаю следующее:

this->threadMediaWorker = new QThread(); 
this->mediaWorker = new MediaWorker(); 
this->timerMediaWorker = new QTimer(); 
this->timerMediaWorker->setInterval(1000); 

this->timerMediaWorker->moveToThread(this->threadMediaWorker); 
this->mediaWorker->moveToThread(this->threadMediaWorker); 

connect(this->threadMediaWorker, SIGNAL(started()), this->timerMediaWorker, SLOT(start())); 
connect(this->timerMediaWorker, &QTimer::timeout, this->mediaWorker, &MediaWorker::OnExecuteProcess); 

connect(this->mediaWorker, &MediaWorker::Finished, this->threadMediaWorker, &QThread::quit); 
connect(this->mediaWorker, &MediaWorker::Finished, this->mediaWorker, &MediaWorker::deleteLater); 
connect(this->threadMediaWorker, &QThread::finished, this->mediaWorker, &QThread::deleteLater); 

this->threadMediaWorker->start(); 

резьба работает правильно. Когда я закрываю приложение I прекратить поток в деструкторе:

MainWindow::~MainWindow() 
{ 
    delete ui; 

    this->mediaWorker->Exit(); 
} 

так Выход() испускается Готовое сигнал, который мы надеемся удалить QThread и mediaworker класс.

Вопрос в том, является ли это правильным способом прекращения как рабочего процесса, так и рабочего класса?

ответ

1

Мой вопрос заключается в том, что является надлежащим способом прекращения рабочего потока работника и рабочего класса ?

Вы можете просто убедиться, что объект «СМИ» будет удален, а главное окно получает уничтожены либо с помощью QScopedPointer или std::unique_ptr.

class MainWindow : public QMainWindow { 
    /// ... 
    QThread m_workerThread; 
    QScopedPointer<MediaWorker> m_pMediaObject; 
    /// ... 
}; 

void MainWindows::init() 
{ 
    // ... other initialization skipped ... 
    // for dynamic allocation of the object and keeping the track of it 
    m_mediaObject.reset(new MediaWorker()); 
    m_workerThread.moveToThread(m_mediaObject.data()); 
} 

void MainWindow::stopWorker() 
{ 
    if (m_workerThread.isRunning()) 
    { 
     m_workerThread.quit(); // commands Qt thread to quit its loop 
           // wait till the thread actually quits 
     m_workerThread.wait(); // possible to specify milliseconds but 
           // whether or not to limit the wait is 
           // another question 
    } 
} 

Если рабочий поток используется для обновления пользовательского интерфейса имеет смысл попытаться остановить рабочий поток до объектов пользовательского интерфейса, выпущенных в

void MainWindow::closeEvent(QCloseEvent *) 
{ 
    stopWorker(); 
} 

Но есть шанс, что главное окно никогда не получает closeEvent() называется до разрушения, так что мы должны справиться с этим:

MainWindow::~MainWindow() 
{ 
    stopWorker(); 

    // it also destroys m_mediaObject 
} 
+0

Спасибо за образец – adviner

+0

в Qt документации на [QThread] (Http: //doc.qt .io/qt-5/qthread.html # terminate) также предоставляет простой пример использования, включая предпочтительную процедуру запуска и выхода. – m7913d