Search code examples
c++qtopencvqmlqquickitem

Asynchronously update multiple QQuickPaintedItem on QML


I am trying to use a class which inherits from QQuickPaintedItem to display video frames captured with openCV.

in this class, there is a slot called queryFrame() which is connected to a QTimer timout (40ms) by:

connect(m_timer, SIGNAL(timeout()), this, SLOT(queryFrame()));

queryFrame() code:

void CVCamScreen::queryFrame()
{
    if(!m_url.isEmpty()){
        if( !m_capture->isOpened() ) {
            m_capture->open( m_url.toStdString() );
        }

        cv::Mat frame;
        m_capture->read( frame );

        m_qImage = ipl2Qimg(new IplImage(frame));

        update();

        emit frameChanged();
    }
}

Everytime queryFrame() is called it should update the view. It is doing this, but it is not working asynchronously.

How should I make each of this CVCamScreen update itself in an independent way?

QML code which renders the CamScreens:

Repeater {
    model: 8

    CVCamScreen {
        Layout.fillWidth: true
        Layout.fillHeight: true

        url: Controller.urlCanal(index + 1)

        CustomBorder {
            commonBorder: true
            color: "#228e14"
            commonBorderWidth: 3
        }

        onUrlChanged: {
            start(); // starts the timer when the URL changes.
        }
    }
}

Solution

  • Your problem is that all CVCamScreen objects are in the same thread. So, timer events are delivered sequentially to them. I would suggest to move actual reading from device and ipl2Qimg() stuff into a background thread which would just notify CVCamScreen when data is ready and update() should be called.