如何将QGraphicsView定位到鼠标双击位置?已试centerOn/translate无效
解决QGraphicsView双击后无法定位到鼠标位置的问题
我看了你的代码,发现问题主要出在场景范围过小以及视图默认缩放行为的影响上,导致centerOn的效果看起来不明显甚至没生效。下面给你一步步分析和修复:
问题根源拆解
- 场景空间不足:你只添加了一个100x100的椭圆,场景的
boundingRect被限制在这个椭圆的范围内。QGraphicsView默认会自动缩放视图以适配整个场景,所以初始时椭圆会被放大填满600x600的窗口。此时双击视图任意位置,转换后的场景坐标都落在椭圆范围内,而视图已经把这个范围居中显示了,所以调用centerOn看起来没有变化。 - 缺少可滚动的场景区域:要让
centerOn的滚动效果直观体现,场景需要有足够大的范围,允许视图滚动到不同位置。
修复后的完整代码
我调整了代码的关键部分,确保双击定位功能正常工作:
from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * import sys class SurfViewer(QMainWindow): def __init__(self, parent=None): super(SurfViewer, self).__init__() self.parent = parent self.setFixedWidth(600) self.setFixedHeight(600) photo = PhotoViewer() self.setCentralWidget(photo) class PhotoViewer(QGraphicsView): def __init__(self, parent=None): super(PhotoViewer, self).__init__(parent) self.parent = parent self.scene = QGraphicsScene(self) # 设置足够大的场景范围,提供滚动空间 self.scene.setSceneRect(-500, -500, 1000, 1000) self.setScene(self.scene) self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) self.setResizeAnchor(QGraphicsView.AnchorUnderMouse) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.setFrameShape(QFrame.NoFrame) # 添加背景矩形,方便直观看到场景范围 bg_item = QGraphicsRectItem(-500, -500, 1000, 1000) bg_item.setBrush(QBrush(Qt.lightGray, style=Qt.SolidPattern)) self.scene.addItem(bg_item) self.UpdateScene() def mouseDoubleClickEvent(self, event): # 获取视图坐标并转换为场景坐标 view_pos = event.pos() scene_pos = self.mapToScene(view_pos) print(f"双击的场景坐标: {scene_pos.x()}, {scene_pos.y()}") # 将该场景坐标设为视图中心 self.centerOn(scene_pos) # 无需手动调用update,centerOn会自动触发视图更新 def UpdateScene(self): xsize=100 ysize=100 newitem = QGraphicsEllipseItem(0-xsize/2., 0-ysize/2., xsize, ysize) newitem.setBrush(QBrush(Qt.black, style = Qt.SolidPattern)) self.scene.addItem(newitem) if __name__ == '__main__': app = QApplication(sys.argv) ex = SurfViewer(app) ex.setWindowTitle('window') ex.show() sys.exit(app.exec_())
关键修改说明
- 扩大场景范围:通过
self.scene.setSceneRect(-500, -500, 1000, 1000)定义了一个1000x1000的场景,让视图有足够空间滚动。 - 添加背景参考:新增的浅灰色背景矩形能让你直观看到场景边界,测试时可以清晰观察到视图中心的变化。
- 简化事件处理:移除了不必要的
update()调用,因为centerOn会自动触发视图的重绘和滚动逻辑。
现在运行修改后的代码,双击视图任意位置,视图就会自动滚动,将你双击的位置设为视图中心了。
内容的提问来源于stack exchange,提问作者ymmx
相关产品推荐
相关产品推荐

