不幸的是,我得到了ASSERT错误:
ASSERT: "!unindexedItems.contains(item)" in file graphicsview\qgraphicsscenebsptreeindex.cpp, line 364
它们似乎是随机发生的。我已经尝试了不同的连接类型,但没有结果。
我正在循环中启动线程。
我正在使用Qt 5.0。
不幸的是,我得到了ASSERT错误:
ASSERT: "!unindexedItems.contains(item)" in file graphicsview\qgraphicsscenebsptreeindex.cpp, line 364
它们似乎是随机发生的。我已经尝试了不同的连接类型,但没有结果。
我正在循环中启动线程。
我正在使用Qt 5.0。
一般而言,使用Qt时,在GUI线程之外不能执行任何GUI操作(即执行QApplication::exec()的线程,通常是main()线程)。
因此,如果您有多个线程操纵QGraphicsItems(特别是当前作为QGraphicsScene一部分的QGraphicsItems),那么这很可能是断言失败的原因。也就是说,在Qt GUI线程执行窗口刷新时,它会从各种QGraphicsItem对象中读取数据作为其计算的一部分,并且期望QGraphicsItems在刷新操作期间保持不变。如果在刷新例程执行过程中更改了QGraphicsItem(由另一个线程),则主线程进行的计算可能会变得错误/损坏,并且偶尔会引起断言失败(和/或其他不希望的行为)。
如果您确实需要使用多个线程,那么您可能需要让线程在自己的私有数据结构上进行所有计算,Qt GUI线程无法访问该数据结构。然后,当线程计算出结果时,它们应将结果发送回Qt GUI线程(通过queued connection或QApplication::postEvent())。然后,GUI线程可以查看结果并使用它们更新QGraphicsItems等;这将是“安全”的,因为此更新不能在窗口更新的中间发生。
如果这听起来太麻烦,那么您可以考虑只在GUI线程中进行所有操作;以这种方式让一切都能可靠地运行会更容易和简单。
如 Jeremy 所提到的,Qt 渲染必须在主线程上完成。
尽管您可以将所有内容移动到主线程上,但很可能会选择为了效率而创建单独的线程,特别是因为碰撞检测可能会占用处理器。最好的方法是将对象的建模和物理分离出来,就像在模型/视图/控制器模式中一样。
创建不从任何 QGraphicsItem/Object 派生的身体实例表示。这些实例可以在不同的线程上进行计算,并向在主线程上运行的图形对象发出信号,该信号更新每个身体实例的图形表示,从而允许轨迹实时呈现。