You can, of course, use the C++ Standard Library classes in your code. For example, use std::mutex
to update image as follows:
void CameraView::updateImage(const QImage& image) {
std::unique_lock<std::mutex> lock(mutex); // std::mutex object is located elsewhere
// ... the rest of the code as before ...
}
You can also leave CameraView
code unchanged and call the updateImage
function from external code. Just make sure that the image is updated using the same mutex in all threads:
void functionInAnotherThread(CameraView& cameraView) {
std::unique_lock<std::mutex> lock(mutex); // std::mutex object is located elsewhere
// ... the rest of the code ...
cameraView.updateImage(image);
// ... the rest of the code ...
}
Let's try to implement this approach. Let's change the header file a bit:
class CameraView : public QQuickPaintedItem {
Q_OBJECT
Q_DISABLE_COPY(CameraView)
public:
CameraView(QQuickItem* parent = nullptr);
public slots:
void updateImage(const QImage&);
void scheduleUpdate();
protected:
QImage image_;
};
Now, write the definitions of the methods:
void CameraView::updateImage(const QImage& image) {
image_ = image.copy(); // Does deep copy of image data.
}
void CameraView::scheduleUpdate() {
update();
}
void CameraView::paint(QPainter* painter) {
painter->drawImage(this->boundingRect(), image_);
}
Finally, we write the function of updating the picture and scheduling redrawing:
void functionInAnotherThread(CameraView& cameraView) {
std::unique_lock<std::mutex> lock(mutex); // std::mutex object is located elsewhere
cameraView.updateImage(image);
lock.unlock(); // Unlock the mutex as we have already updated the image.
QMetaObject::invokeMethod(&cameraView, "scheduleUpdate",
Qt::QueuedConnection); // Call slot through the queued connection.
}
With Qt::QueuedConnection
, the slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread. Thus, we can schedule the widget to be redrawn from another thread. Try using other types of connections if this does not work.