2016-12-31 2 views
0

Ich habe folgende Arbeiter Klasse:Beenden QThread wenn GUI-Anwendung verlässt

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

    void Exit(); 

signals: 
    void Finished(); 

public slots: 
    void OnExecuteProcess(); 
}; 

In MediaWorker.cpp

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

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

In meinem Mainwindow ich folgendes:

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(); 

Die Threading funktioniert ordnungsgemäß. Wenn ich die Anwendung schließe ich den Thread im destructor beenden:

MainWindow::~MainWindow() 
{ 
    delete ui; 

    this->mediaWorker->Exit(); 
} 

so Exit(), um die Fertig-Signal aussendet, das hoffentlich die QThread und mediaworker Klasse löschen.

Meine Frage ist, ob dies der richtige Weg ist, sowohl die Thread- als auch die Media-Worker-Klasse zu beenden?

Antwort

1

Meine Frage ist, was ist der richtige Weg zum Beenden sowohl der Arbeiter-Thread und Media Worker-Klasse?

Sie können nur sicherstellen, dass das Objekt ‚Medien‘, während das Hauptfenster, indem Sie entweder QScopedPointer oder std::unique_ptr zerstört wird gelöscht wird.

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 
    } 
} 

Wenn der Arbeiter-Thread für die Aktualisierung der Benutzeroberfläche verwendet es sinnvoll, den Arbeitsthread zu stoppen, bevor die UI-Objekte in

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

freigegeben, um zu versuchen macht Aber es gibt eine Chance, dass das Hauptfenster wird nie closeEvent() vor der Zerstörung genannt, so sollten wir damit umgehen:

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

    // it also destroys m_mediaObject 
} 
+0

Danke für die Probe – adviner

+0

die Qt-Dokumentation von [QThread] (http: //doc.qt .io/qt-5/qthread.html # terminate) bietet auch ein klares Anwendungsbeispiel einschließlich der bevorzugten Start- und Beendigungsprozedur. – m7913d

Verwandte Themen