I'm trying to implement a multithreaded app that displays video using the OpenCV libraries (following the example given here).
I create two threads from the GUI thread that successfully terminate when the MainWindow is closed. However, the program still keeps on running (I have to use the stop button on the application output panel to close it down).
Here's my destructor for the MainWindow
MainWindow::~MainWindow()
{
captureThread.quit();
converterThread.quit();
if (captureThread.wait())
qDebug() << "Capture Thread has exited successfully";
if (converterThread.wait())
qDebug() << "Converter Thread has exited successfully";
delete ui;
}
The Application Output window returns the following output on both the Debug and Release builds
Capture Thread has exited successfully
Converter Thread has exited successfully
However, the application only quits in Debug mode.
From what I have gathered from a few google searches is that the application continues on running IF there is a thread that has not been properly terminated. Can that be the case here? If yes, then how may I know which other thread is also running in the program, so that I may terminate/quit it?
Using Qt 5.4 with MSVC 2013 and OpenCV 3.0 beta on Win 8.1
Edit I create my threads in MainWindow constructor
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// registers the type cv::Mat. After a type is registered, one can create/destroy objects at runtime
qRegisterMetaType<Mat>();
// Initializing class' instance
Capture* capture = new Capture;
Converter* converter = new Converter;
ui->labelFrame->setAttribute(Qt::WA_OpaquePaintEvent);
converter->setProcessAll(false);
capture->moveToThread(&captureThread);
converter->moveToThread(&converterThread);
converter->connect(capture, SIGNAL(matReady(Mat)), converter, SLOT(processFrame(Mat)));
this->connect(converter, SIGNAL(imageReady(QImage)), this, SLOT(setImage(QImage)));
// thread clean up
connect(&captureThread, SIGNAL(finished()), &captureThread, SLOT(deleteLater()));
connect(&converterThread, SIGNAL(finished()), &converterThread, SLOT(deleteLater()));
QObject::connect(capture, &Capture::started,
[](){ qDebug() << "capture started"; });
QMetaObject::invokeMethod(capture, "start");
captureThread.start();
converterThread.start();
Edit 2 : I modified my main.cpp to this
QApplication a(argc, argv);
MainWindow w;
w.show();
int ret;
ret = a.exec();
qDebug() << "QApplication.exec() returns " << ret;
return ret;
and I received the following message in the Application output window
QApplication.exec() returns 0
Capture Thread has exited successfully
Converter Thread has exited successfully
which is confusing, since the QApplication should quit after the threads have been stopped. so I moved the thread cleanup to the abouttoQuit()
slot. The order of exiting has changed by this modification but the original problem remains. (The wrong order could be due to the implementation of the qDebug() function, but thats just me guessing)
PS I even added captureThread.terminate()
and converterThread.terminate()
in the destructor but still the results are the same.