【问题标题】:Pixmap shared between threads in QtQt中线程之间共享的像素图
【发布时间】:2016-02-27 12:36:33
【问题描述】:

我有一个主要的 GUI 类和另一个 Worker 类:第一个处理 GUI 事物(将 QPixmap 绘制成 QGraphicsScene),第二个处理计算事物(绘制 QLines 和 QPoint s 到那个QPixmap)。 这两个类在两个不同的线程中运行。 当我创建Worker 线程时,我将GUI 的QPixmap 的地址传递给Worker 类,因此它们共享同一个对象。

QPixmapWorker 类中修改,并在GUI 类中绘制。即使我没有任何问题,我还是决定使用QMutex 来确保我的程序在绘制时不会尝试访问QPixmap。现在,为了做到这一点,我在 GUI 类和 Worker 类之间共享了一个 QMutexWorker 类又有一个指向 GUI 的 QMutex 的指针)。每当我阅读或修改QPixmap 时,我都会锁定QMutex

这是一种有效的方法吗?到目前为止我从未遇到过错误,但我想知道它在逻辑上是否正确以及 Qt 是否提供了更好的方法来完成此操作。

提前谢谢你。

【问题讨论】:

    标签: c++ multithreading qt qpixmap qmutex


    【解决方案1】:

    根据Qt5 thread-safety page

    QPainter 可以在线程中用于在 QImage、QPrinter 和 QPicture 绘画设备。在 QPixmaps 和 QWidgets 上绘画不是 支持。

    所以官方的说法是不,你不应该在主线程之外修改 QPixmap。您可能会“走运”,因为它恰好在您当前的用例下在您当前的平台上工作,但 Qt 不保证它会工作。

    一种更安全的方法可能是让您的工作线程改为绘制 QImage 对象,然后当 GUI 线程想要更​​新 GUI 时,它可以抓取并绘制最新版本的 QImage 对象(使用互斥锁或其他一些确保工作线程不会同时更新 QImage 的机制。

    【讨论】:

    • 那么,如果我使用 QImage 而不是 QPixmap,我的方法是否有效?
    • 不使用 QMutex,只需让工作线程以最新的 QImage 作为参数发出信号,例如: newImageCreated(QImage image);由于 Qt 的 Queued 连接,这是自动线程安全的,并且由于 QImage 是隐式共享的,因此实际上并没有复制数据。这在概念上比使用互斥锁手动锁定要简单得多。
    【解决方案2】:

    我同意根据文档,不允许在工作线程中使用 QPixmap。但是,根据代码。

    构造函数检查它是否在主线程中。如果它不在主线程中,它会检查一个名为 ThreadedPixmap 的功能。如果启用,它将继续没有问题。据我所知,所有平台都支持 ThreadedPixmap,因此似乎可以在其他线程上使用 QPixmap。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-19
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      相关资源
      最近更新 更多