I am making a Qt GUI application that uses a custom QLabel
class (name as ImageInteraction
) to show images from a streaming camera while also allowing mouse interaction on the image. As the GUI has other functionalities, the customized QLabel class does the job of extracting the image from the camera and updating its shown image through a while
loop in a function which is run in another thread. The code for that is as below:
void ImageInteraction::startVideo()
{
if (!capture.open(streamUrl))
{
QMessageBox::warning(this, "Error", "No input device availabe!");
}
else
{
QFuture<void> multiprocess = QtConcurrent::run(this, &ImageInteraction::loadVideo);
}
}
void ImageInteraction::loadVideo()
{
while(loopContinue){
cv::Mat frame;
capture.read(frame);
if(!frame.empty())
{
cv::cvtColor(frame, frame, CV_BGR2RGBA);
cv::resize(frame, frame, cv::Size(this->width(), this->height()), 0, 0);
QImage image(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGBA8888);
this->setPixmap(QPixmap::fromImage(image));
}
}
capture.release();
}
Here capture
is of type cv::VideoCapture
and loopContinue
is a boolean type which is initially set to be true
. There is a closeEvent()
function that invokes the method for stopping the capture of the image from the camera.
void MainWindow::closeEvent(QCloseEvent *event)
{
liveVideo->stopVideoThread();//liveVideo is a pointer to an object of ImageInteraction
event->accept();
}
where stopVideoThread
simply sets the boolean flag loopContinue
to false
and has the following simple code:
void ImageInteraction::stopVideoThread()
{
mutex.lock();//QMutex mutex;
loopContinue = false;
mutex.unlock();
}
In my understanding the while
loop in loadVideo
method should be stopped once stopVideoThread
method is invoked and loopContinue
is set to false. But in reality, when the close button is pressed, apparently it doesn't stop while
loop and the application crashes with a message:
The inferior stopped because it received a signal from the operating system.
Signal name : SIGSEGV
Signal meaning : Segmentation fault
Am I using QtConcurrent::run
method and the QMutex
object erroneously? Could you identify what the problem is? FYI, the OS is ubuntu 14.04 and IDE is QtCreator.
Thanks!
The following is just an idea of the improvements mentioned in the above comments.
class ImageInteraction
{
public:
~ImageInteraction()
{
multiprocess_.waitForFinished();
}
void startVideo()
{
if (!capture.open(streamUrl))
{
QMessageBox::warning(this, "Error", "No input device availabe!");
}
else
{
multiprocess_ = QtConcurrent::run(this, &ImageInteraction::loadVideo);
}
}
void loadVideo()
{
while(loopContinue_)
{
cv::Mat frame;
capture.read(frame);
if(!frame.empty())
{
cv::cvtColor(frame, frame, CV_BGR2RGBA);
cv::resize(frame, frame, cv::Size(this->width(), this->height()), 0, 0);
QImage image(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGBA8888);
this->setPixmap(QPixmap::fromImage(image));
}
}
capture.release();
}
void stopVideoThread()
{
loopContinue_ = false;
//multiprocess_.waitForFinished(); // you can call this here if you want to make sure that the thread has finished before returning
}
private:
QFuture<void> multiprocess_;
std::atomic<bool> loopContinue_;
};