以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
Calling `QQuickPaintedItem::updateImage(const QImage& image)` in a thread safe way (no QThread)
我正在阅读这个关于在C++中创建自定义QQuickPaintedItem
的答案 如何在QQuickPaintedItem 中以有效的方式绘制顺序图像
我想编写不依赖于Qt的代码。也就是说,我不想依赖QThread。我只想从std::thread
打电话给CameraView::updateImage(const QImage& image)
,而不是 qQThread
。可能吗?
我只是简单地创建一个线程,将CameraView
实例传递给它,然后从线程调用它。但是,这不是线程安全的。
如何以线程安全的方式调用CameraView::updateImage(const QImage& image)
?
当然,您可以在代码中使用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
,当控制返回到接收线程的事件循环时,时隙被调用。该插槽在接收器的线程中执行。因此,我们可以安排从另一个线程重绘小部件。如果这不起作用,请尝试使用其他类型的连接。
相关文章:
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- 将 cv::mat 转换为 QImage
- Inference pytorch C++ with alexnet and cv::imread image
- 如何在QTextEdit中添加URL或IMAGE-URL
- 将 QImage 从 c++ 客户端发送到 python 服务器
- Read OpenCV Mat 16bit to QImage 8bit Greyscale
- JNA 将 HICON 转换为 Java Image
- QImage::p ixel 和 QImage::setPixel 坐标超出范围误差
- 如何从路径加载 QImage?
- 在 QListWidget 中旋转 QImage
- 如何为QImage检测足够的格式(数据类型)以消耗最少的RAM
- 优化从文件加载QImage
- Qt-工作线程崩溃时将cv::Mat转换为QImage
- 如何在c++中将image.jpg转换为image.ppm
- QImage:加载图像时自动检测格式
- Qt - 将空指针(原始数据)转换为 QImage 并将其显示在标签上
- Magick++ Blob to Image Error
- 我可以在将项目编译为静态库(未定义的引用)时在代码中使用 QImage 吗?
- 将带有零的 Mat 内核填充到 Image 的大小
- 将 QImage 保存到字节数组