Конечно, вы можете использовать классы стандартной библиотеки C ++ в своем коде. Например, используйте std::mutex
для обновления изображения следующим образом:
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 ...
}
Вы также можете оставить код CameraView
без изменений и вызвать функцию updateImage
из внешнего кода. Просто убедитесь, что изображение обновляется с использованием одного и того же мьютекса во всех потоках:
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 ...
}
Давайте попробуем реализовать этот подход. Давайте немного изменим заголовочный файл:
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_;
};
Теперь запишем определения методов:
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_);
}
Наконец, мы напишем функцию обновления изображения и планирования перерисовки:
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.
}
При Qt::QueuedConnection
слот вызывается, когда управление возвращается к событию l oop потока получателя. Слот выполняется в потоке получателя. Таким образом, мы можем запланировать перерисовку виджета из другого потока. Попробуйте использовать другие типы соединений, если это не работает.