QConcurrent::run 的 QMutex 没有按预期工作?
QMutex with QConcurrent::run not working as expected?
我正在制作一个 Qt GUI 应用程序,它使用自定义 QLabel
class(名称为 ImageInteraction
)来显示来自流式摄像机的图像,同时还允许在图像上进行鼠标交互.由于 GUI 具有其他功能,自定义的 QLabel class 完成了从相机中提取图像并通过 while
循环更新其显示图像的工作,该循环在另一个函数中为 运行线。代码如下:
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();
}
这里capture
是cv::VideoCapture
类型,loopContinue
是boolean类型,初始设置为true
。有一个 closeEvent()
函数调用停止从相机捕获图像的方法。
void MainWindow::closeEvent(QCloseEvent *event)
{
liveVideo->stopVideoThread();//liveVideo is a pointer to an object of ImageInteraction
event->accept();
}
其中 stopVideoThread
只是将布尔标志 loopContinue
设置为 false
并具有以下简单代码:
void ImageInteraction::stopVideoThread()
{
mutex.lock();//QMutex mutex;
loopContinue = false;
mutex.unlock();
}
根据我的理解,一旦 stopVideoThread
方法被调用并且 loopContinue
设置为 false,loadVideo
方法中的 while
循环应该停止。但实际上,当按下关闭按钮时,显然它不会停止 while
循环并且应用程序崩溃并显示一条消息:
The inferior stopped because it received a signal from the operating system.
Signal name : SIGSEGV
Signal meaning : Segmentation fault
我是否错误地使用了 QtConcurrent::run
方法和 QMutex
对象?你能确定是什么问题吗?仅供参考,OS 是 ubuntu 14.04,IDE 是 QtCreator。
谢谢!
以下只是对上述评论中提到的改进的想法。
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_;
};
我正在制作一个 Qt GUI 应用程序,它使用自定义 QLabel
class(名称为 ImageInteraction
)来显示来自流式摄像机的图像,同时还允许在图像上进行鼠标交互.由于 GUI 具有其他功能,自定义的 QLabel class 完成了从相机中提取图像并通过 while
循环更新其显示图像的工作,该循环在另一个函数中为 运行线。代码如下:
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();
}
这里capture
是cv::VideoCapture
类型,loopContinue
是boolean类型,初始设置为true
。有一个 closeEvent()
函数调用停止从相机捕获图像的方法。
void MainWindow::closeEvent(QCloseEvent *event)
{
liveVideo->stopVideoThread();//liveVideo is a pointer to an object of ImageInteraction
event->accept();
}
其中 stopVideoThread
只是将布尔标志 loopContinue
设置为 false
并具有以下简单代码:
void ImageInteraction::stopVideoThread()
{
mutex.lock();//QMutex mutex;
loopContinue = false;
mutex.unlock();
}
根据我的理解,一旦 stopVideoThread
方法被调用并且 loopContinue
设置为 false,loadVideo
方法中的 while
循环应该停止。但实际上,当按下关闭按钮时,显然它不会停止 while
循环并且应用程序崩溃并显示一条消息:
The inferior stopped because it received a signal from the operating system.
Signal name : SIGSEGV
Signal meaning : Segmentation fault
我是否错误地使用了 QtConcurrent::run
方法和 QMutex
对象?你能确定是什么问题吗?仅供参考,OS 是 ubuntu 14.04,IDE 是 QtCreator。
谢谢!
以下只是对上述评论中提到的改进的想法。
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_;
};