c++ - 从 Qt 中的多个线程绘制

标签 c++ multithreading qt synchronization

我正在用 Qt 编写一个程序,它运行 10 个工作线程来计算物体在空间中的轨迹。他们还必须绘制对象的路径。我有一个派生 QGraphicsEllipseItem 的“Body”类,它里面有一个 QPainterPath。 “模拟”类采用世界上的障碍物列表,模拟并运行 body ,直到 body 与某物发生碰撞。模拟在单独的线程中运行(通过 moveToThread 完成,而不是通过继承 QThread)。当 body 发生碰撞时,模拟会发出一个信号,表明它已完成。当所有线程都完成后,我想绘制路径(我通过调用“Body”中的一个方法来实现,该方法在其 draw 方法中启用路径绘制)。

不幸的是,我收到 ASSERT 错误:

ASSERT: "!unindexedItems.contains(item)" in file graphicsview\qgraphicsscenebsptreeindex.cpp, line 364

它们看似随机发生。我尝试了不同的连接类型,但没有结果。
我正在循环启动线程。
我正在使用 Qt 5.0

最佳答案

一般来说,对于 Qt,您不能在 GUI 线程(即执行 QApplication::exec() 的线程,通常是 main() 线程)之外执行任何 GUI 操作。

因此,如果您有多个线程操作 QGraphicsItems(尤其是当前属于 QGraphicsScene 的 QGraphicsItems),这很可能是断言失败的原因。也就是说,当 Qt GUI 线程进行窗口刷新时,它从各种 QGraphicsItem 对象读取数据作为其计算的一部分,并且它期望 QGraphicsItems 在刷新操作期间保持不变。如果在执行刷新例程时(由另一个线程)更改 QGraphicsItem,则主线程进行的计算可能会出错/损坏,并且偶尔会导致断言失败(和/或其他不需要的行为)。

如果您真的需要使用多线程,您可能需要做的是让线程在 Qt GUI 线程无法访问的它们自己的私有(private)数据结构上进行所有计算。然后,当线程计算出它们的结果时,它们应该将结果发送回 Qt GUI 线程(通过排队连接或 QApplication::postEvent())。然后 GUI 线程可以查看结果并使用它们来更新 QGraphicsItems 等;这将是“安全的”,因为此更新不会发生在窗口更新的中间。

如果这听起来工作量太大,那么您可能会考虑在 GUI 线程中完成所有工作;以这种方式使一切可靠地工作将变得更加容易和简单。

关于c++ - 从 Qt 中的多个线程绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16258346/

相关文章:

c++ - 空析构函数与文字析构函数

c++ - 为什么 IHTMLImgElement 方法 put_src 在从线程调用时返回 E_OUTOFMEMORY?

java - 套接字上的客户端的高性能多线程

c++ - QLineEdit:将光标位置设置为焦点开始

c++ - 如何在小部件上单击 "What' s“此”按钮时得到通知?

c++ - AppleClang : Operator Overloading Compilation Error

c++ - 连接到同一网络中的命名管道,无需管理员权限

c++ - QTimeEdit : how to create an object of "QTime::setHMS(int, int, int, int)"?

java - 执行线程 "one by one"

python - 是否可以更改 QTableWidget 行标签的颜色?