Qt中线程间共享Pixmap

4
我有一个主GUI类和另一个Worker类:第一个处理GUI事务(将QPixmap绘制到QGraphicsScene中),第二个处理计算事务(在该QPixmap上绘制QLine和QPoint)。这两个类在两个不同的线程中运行。当我创建Worker线程时,将GUI的QPixmap地址传递给Worker类,因此它们共享相同的对象。
QPixmap在Worker类中被修改,并在GUI类中被绘制。即使我没有任何问题,我决定使用QMutex确保程序在绘制QPixmap时不会尝试访问它。现在,为了做到这一点,我在GUI类和Worker类之间共享一个QMutex(Worker类再次具有指向GUI的QMutex的指针)。每当我读取或修改QPixmap时,我都会锁定QMutex。
这是一种有效的方法吗?到目前为止,我从未收到过错误,但我想知道它是否在逻辑上正确,以及Qt是否提供更好的方法来实现此目的。
提前感谢您。
2个回答

4
根据 Qt5线程安全页面,可以在线程中使用QPainter绘制到QImage、QPrinter和QPicture设备上。不支持绘制到QPixmaps和QWidget上。
因此,官方的说法是不应该在主线程之外修改 QPixmap。您可能“有点运气”,因为它恰好在您当前的平台和使用情况下可以工作,但 Qt 不保证它会正常工作。
更安全的方法可能是让您的工作线程先绘制到 QImage 对象中,然后当 GUI 线程想要更新 GUI 时,可以获取并绘制 QImage 对象的最新版本(使用互斥锁或其他机制确保工作线程不会同时更新 QImage)。

那么,如果我使用 QImage 而不是 QPixmap,我的方法是否有效? - Michael
2
不要使用QMutex,而是让工作线程发出一个带有最新QImage参数的信号,例如:newImageCreated(QImage image)。这是由于Qt的Queued连接自动保证了线程安全,而且由于QImages是隐式共享的,所以数据实际上并没有被复制。这在概念上比手动使用互斥锁要简单得多。 - ScottG

2

根据文档,不允许在工作线程中使用QPixmap。然而,根据代码。

构造函数检查是否在主线程中。如果不在主线程中,则检查名为ThreadedPixmap的功能。如果启用了该功能,则可以继续使用,没有问题。据我所见,ThreadedPixmap在所有平台上都受支持,因此似乎可以在其他线程上使用QPixmaps。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接