我正在使用QThread捕获相机帧(OpenCV)的应用程序上工作。我遵循了described here的方法,并将一个工作程序移至QThread:
m_CameraCaptureThread= new QThread();
m_ProcessingThread= new QThread();
m_CameraCapture= new CCameraCapture();
//Move camera capture object to thread
m_CameraCapture->moveToThread(m_CameraCaptureThread);
//Connect error signal
QObject::connect(m_CameraCapture, SIGNAL(error(QString,QString)), this, SLOT(reportError(QString,QString)));
//Connect the finished signal of the worker class to the thread for quitting the loop
QObject::connect(m_CameraCapture, SIGNAL(finished()), m_CameraCaptureThread, SLOT(quit()));
//This connections guarantees that the *m_CVideoCapture is automatically deleted if the event loop of the thread is terminated. Therefore, m_CVideoCapture does not need to be released manually if the capturing process is stopped.
QObject::connect(m_CameraCaptureThread, SIGNAL(finished()), m_CameraCaptureThread, SLOT(deleteLater()));
QObject::connect(m_CameraCapture, SIGNAL(finished()), m_CameraCapture, SLOT(deleteLater()));
QObject::connect(this, SIGNAL(exitThreads()), m_CameraCapture, SLOT(exitThread()));
此代码是我的相机处理程序类的构造函数的一部分。如果主应用程序已关闭,我想退出所有线程。因此,我的CCameraHandler的析构函数是:
CCameraHandler::~CCameraHandler(void)
{
emit exitThreads();
qDebug() << "CCameraHandler deleted";
}
我的摄像机捕获中的退出插槽(由信号exitThreads()调用)是:
void CCameraCapture::exitThread(){
//Stop grabbing
stopGrabbing();
//Emit finished signal which should be connected to quit() of QThread and deleteLate of this class;
emit finished();
}
从连接设置中可以看出,发出的finish()信号将退出线程的事件循环,并调用Worker和Thread的deleteLater()。被称为worker的析构函数如下:
CCameraCapture::~CCameraCapture(void)
{
qDebug() << "CCameraCapture deleted";
}
结果是正确调用了CCameraCapture的Destructor-它仅在QDebug流中出现一次,但在CCameraCapture::〜CCameraCapture(void)范围的末尾出现。我从OpenCVs opencv_highgui249d.dll收到访问冲突错误。由于我只使用:
cv::VideoCapture m_Cap;
在CCameraCapture的类定义中,销毁m_Cap必须导致此错误。目前,我真的不知道如何解决这个问题。有任何想法吗?
编辑:
使用以下命令关闭主窗口时,应用程序应关闭
this->setAttribute(Qt::WA_DeleteOnClose);
和
CMainWindow::~CMainWindow(){
m_CameraHandler->deleteLater();
m_ImageWidget->deleteLater();
m_ProcessedImageWidget->deleteLater();
emit windowClosed();
qDebug() << "CMainWindow deleted";
}
最佳答案
如果不自己调试,似乎是CCameraHandler的析构函数中的emission的问题。
有问题的一个原因是,如果用户关闭应用程序并退出主事件循环(从QApplication对exec的调用开始),则实际上不会删除任何已调用deleteLater的对象。在这种情况下,我专门查看m_CameraCaptureThread。
如果我们经历信号/插槽的事件处理:-
通过调用deleteLater,在插槽功能退出后,将一个事件放置在当前线程的事件队列中以处理删除。当事件循环接下来处理事件时,会发生这种情况。
但是,该应用程序将退出,因此事件循环不会再次运行,并且对deleteLater的调用也不会得到服务。
如果所有对象都在同一线程中运行,则信号/插槽连接是直接的,这将不再是问题。但是,使用多个线程时,连接会排队。
我建议更改析构函数,以便在不使用发出信号的情况下进行清理,以查看问题是否仍然存在。
关于c++ - 使用QThread时如何避免Qt访问冲突错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22831453/