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.
}
}
}
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.