有时选定的项目不会一起移动。
在具有两种类型的项目的应用程序中会发生这种情况:
ItemIgnoresTransformations
标记(在缩放时它们必须保持相同的大小)当它们被一起选中并通过鼠标移动时,它们应该被翻译相同的量(它们应该作为一个整体移动)。当仅移动“常规项目”或仅移动“句柄”时它可以正常工作,但是当选择两种类型时都不行。
这是显示问题的最小示例。 它也可以在sourceforge上找到,还有一个增强版本,还显示了项目的一些属性。
import sys
from PyQt4 import QtGui, QtCore
class View(QtGui.QGraphicsView):
def __init__(self):
QtGui.QGraphicsView.__init__(self)
self.scene = QtGui.QGraphicsScene(self)
#self.scene.setSceneRect(QtCore.QRectF(0, 0, 245, 245))
self.setScene(self.scene)
self.item1 = QtGui.QGraphicsRectItem(0, 0, 60, 40)
self.item1.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
self.item1.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
self.scene.addItem(self.item1)
self.item2 = QtGui.QGraphicsRectItem(0, 0, 40, 60)
self.item2.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True)
self.item2.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True)
self.item2.setFlag(QtGui.QGraphicsItem.ItemIgnoresTransformations, True)
self.scene.addItem(self.item2)
self.item1.setSelected(True)
self.item2.setSelected(True)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
view = View()
view.show()
sys.exit(app.exec_())
两个项目都已被选中。单击一个项目并拖动(例如向左移动)似乎只移动一个项目。这似乎发生在sceneBoundingRect
更新时。向后移动(向右移动),两者都被翻译在一起,直到sceneBoundingRect
必须再次扩大。
如果未注释setSceneRect
行,则行为正确。
ItemIgnoresTransformations
的{{3}}说
该项忽略继承的变换(即,其位置仍锚定到其父级,但忽略父级或视图旋转,缩放或剪切变换)。此标志对于使文本标签项保持水平和未缩放非常有用,因此如果转换视图,它们仍然可读。设置后,项目的视图几何体和场景几何体将单独维护。您必须调用deviceTransform()来映射坐标并检测视图中的碰撞。默认情况下,禁用此标志。这个标志在Qt 4.3中引入。注意:设置此标志后,您仍然可以缩放项目本身,并且该比例转换将影响项目的子项。
我问了一个关于第一个大胆的句子documentation的具体问题。这可能与此有关。
阅读What is the meaning of "the item's view geometry and scene geometry will be maintained separately"?并搜索,deviceTransform()
似乎没有像更新boundingRect那样做任何神奇的事情。它真的有用吗?怎么样?
在doc中,建议不使用ItemIgnoresTransformations
标志。但这是关于父母/子女的关系。
Maintaining relative child position after applying QGraphicsItem::ItemIgnoresTransformations值得一读,但也更多关于父母/孩子。
This thread也很有趣,但改变原点不会改变这里的核心问题。
所以有几种可能的解决方案(当然,答案显示解决方案也很有用),但我更希望深入解释这里发生的事情。