QGraphicsView坐标系机制解析及自定义Item绘图坐标疑问
QGraphicsItem绘图坐标系全解析
1. paint函数使用的坐标系
在自定义QGraphicsItem的paint()方法中调用painter->drawLine(-50,-50,50,50)时,用的是Item自身的局部坐标系:
- 原点默认是Item的变换原点(默认值为(0,0)),所有绘图坐标都是相对于这个点的。
- 单位默认与Scene保持一致,通常是像素,除非你给Item添加了缩放变换(比如
setScale(2)会让单位放大2倍),或者修改了Scene的坐标映射规则。
2. boundingRect()的真实作用
你返回QRectF(0,0,200,200)时仍能画出超出该范围的线条,是因为boundingRect()不是用来限制绘图区域的,它的核心职责是:
- 告知Qt该Item的边界范围,用于Scene的视图裁剪、碰撞检测、刷新区域计算。
- 绘图内容超出boundingRect不会被强制裁剪,但会导致碰撞检测失效、视图刷新不完整等问题,所以建议让boundingRect包含所有绘图内容。
3. 坐标系的确定与控制逻辑
你的程序结构是QGraphicsView → QGraphicsScene → 自定义Item,三者坐标系的关系及控制方式如下:
局部坐标系(Item自身)
- 默认原点是(0,0),可通过
setTransformOriginPoint(QPointF(x,y))修改变换原点,比如设置为(100,100)后,你在paint里画的(0,0)就对应Item自身的(100,100)位置。 - 可通过Item的变换方法调整坐标系:
setPos(sceneX, sceneY):将Item局部坐标系的原点平移到Scene坐标系的(sceneX, sceneY)位置。setScale(ratio):缩放局部坐标系的单位,比如setScale(0.5)会让绘图内容缩小一半。setRotation(angle):旋转局部坐标系,绘图内容会跟着旋转。
Scene坐标系
- 所有Item的
pos()都是相对于Scene原点(默认(0,0))的坐标。 - 可通过
scene->setSceneRect()修改Scene的可视范围,但不会改变坐标系原点。
View坐标系
- 即QGraphicsView的窗口像素坐标系,Qt会自动将Scene坐标系的内容映射到View坐标系。
- 可通过
view->setTransform()缩放、平移整个视图,但这只会改变内容的显示大小和位置,不会影响Item的局部坐标系。
举个实际例子:
如果你的自定义Item在Scene中的pos()是(200,200),变换原点保持默认(0,0),那么你在paint里画的(-50,-50)点,对应Scene坐标系的位置是(200-50, 200-50)=(150,150),最终会被View映射到窗口的对应像素位置。
内容的提问来源于stack exchange,提问作者Isaac D. Cohen
相关产品推荐
相关产品推荐

