0

I have difficulties to get a Qt::QueuedConnection between a background thread and my main application running. I have a camera capturing class derived from QObject which is moved to a QThread by using:

m_CameraCapture.moveToThread(&m_CameraCaptureThread);

Afterwards, I connect the signals and slots:

    //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
    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()));
    //Connect sendFrame to update frame for displaying the current frame
    QObject::connect(&m_CameraCapture, SIGNAL(sendFrame(cv::Mat)), this, SLOT(receiveFrame(cv::Mat)),Qt::BlockingQueuedConnection);
    QObject::connect(this, SIGNAL(startGrabbing()), &m_CameraCapture, SLOT(startGrabbing()));
    QObject::connect(this, SIGNAL(stopGrabbing()), &m_CameraCapture, SLOT(stopGrabbing()));

The m_CameraCapture object contains a timer which calls in regular intervals the grabFrame() slot of m_CameraCapture. The function is defined by:

void CCameraCapture::grabFrame(){
    QMutexLocker ml(&m_Mutex);
    qDebug() << "Elapsed time " << GetTickCount()-lastTickCount<<" ms";
    qDebug() << "Thread ID timer: " << m_Timer.thread();
    qDebug() << "Thread ID worker: " << this->thread();
    lastTickCount=GetTickCount();       
    //Local image storage
    cv::Mat cvFrameBGR;
    //Get new frame from camera
    m_Cap>>cvFrameBGR;      
    //cv::Mat cvFrameRGB;
    ////Convert frame to RGB
    //cv::cvtColor(cvFrameBGR, cvFrameRGB, CV_BGR2RGB);
    ////Convert cv::Mat to QImage
    //m_Frame=QImage((uchar*)(cvFrameRGB.data),cvFrameRGB.cols,cvFrameRGB.rows,QImage::Format_RGB888);
    //Send frame to receivers
    emit sendFrame(cvFrameBGR);
}

The thread IDs of timer and thread are the same and different to the thread ID of the main application - so this seems to be correct. The point is the line

emit sendFrame(cvFrameBGR);

This signal only arrives at the main application if I use

QObject::connect(&m_CameraCapture, SIGNAL(sendFrame(cv::Mat)), this, SLOT(receiveFrame(cv::Mat)),Qt::BlockingQueuedConnection);

in the main application to connect it. But this is not what I want because it will slow down my capturing loop. I would like to connect it with a Qt::QueuedConnection. However, when I use a QueuedConnection instead of the BlockingQueuedConnection the receiveFrame(cv::Mat) slot in the receiving Object is never executed (Also with AutoConnection it wont work). The receiving Object is a cameraHandler class which is derived from QObject. Thanks for any hint!

00Jan00
  • 117
  • 1
  • 12
  • Is the QThread a member of the CaptureCamera class? If so, I'd look into separating this. When you call moveToThread, it moves the object and its children, which could be an issue here. – TheDarkKnight Mar 27 '14 at 17:22
  • 1
    I don't know what exactly you're doing wrong, but you could start with the working, tested code from [this answer](http://stackoverflow.com/a/21253353/1329652) and see how it differs from whatever you're doing. – Kuba hasn't forgotten Monica Mar 27 '14 at 21:35
  • Why are you taking the mutex in `grabFrame()`? You're not sharing any data in that object with anyone else, right? There's really no reason to share any data, so why the mutex? – Kuba hasn't forgotten Monica Mar 27 '14 at 21:36
  • Thanks Kuba, the QMutexLocker was a left over of different trials I had with this class. As I am new to Qt I was not so sure about the signals, if they will perform a deep copy of my image directly or if there is a chance that the other thread will read the image while it is overwritten in the capture thread with the next frame. – 00Jan00 Mar 28 '14 at 08:19
  • Your linked example code solved my problem because I could directly compare what is different: I did not use Q_DECLARE_METATYPE(cv::Mat) and qRegisterMetaType() Therfore, only Qt::BlockingQueuedConnection worked. QueuedConnection seems to be only possible with the registeredsMetaType(). – 00Jan00 Mar 28 '14 at 08:23

0 Answers0