我想放大 QGraphicsView,以便鼠标下的场景位置保持在鼠标下。以下代码实现了这一点:
from PySide6.QtCore import QPoint
from PySide6.QtWidgets import QGraphicsView, QGraphicsScene, QApplication
import math
class MyGraphicsView(QGraphicsView):
def wheelEvent(self, event):
self.setTransformationAnchor(self.ViewportAnchor.AnchorUnderMouse)
self.setResizeAnchor(self.ViewportAnchor.AnchorUnderMouse)
if event.angleDelta().y() > 0:
self.scale(1.1, 1.1)
elif event.angleDelta().y() < 0:
self.scale(1 / 1.1, 1 / 1.1)
self.setTransformationAnchor(self.ViewportAnchor.NoAnchor)
self.setResizeAnchor(self.ViewportAnchor.NoAnchor)
class MyTestScene(QGraphicsScene):
def drawBackground(self, painter, rect, PySide6_QtCore_QRectF=None, PySide6_QtCore_QRect=None):
left = int(math.floor(rect.left()))
top = int(math.floor(rect.top()))
right = int(math.ceil(rect.right()))
bottom = int(math.ceil(rect.bottom()))
first_left = left - (left % 100)
first_top = top - (top % 100)
for x in range(first_left, right + 1, 100):
for y in range(first_top, bottom + 1, 100):
painter.drawEllipse(QPoint(x, y), 2.5, 2.5)
painter.drawText(x, y, f"{x},{y}")
if __name__ == '__main__':
app = QApplication([])
scene = MyTestScene()
scene.setSceneRect(-2000, -2000, 4000, 4000)
view = MyGraphicsView()
view.setScene(scene)
view.setGeometry(100, 100, 900, 600)
view.setVisible(True)
# view.setInteractive(False)
app.exec()
此代码存在以下问题:
- 如果用户在第一次尝试使用滚轮缩放之前单击了视图(并且该视图是“交互式的”),则一切都会按预期工作。
- 如果不是,在第一个滚轮事件中,场景会“跳跃”(除了正确缩放之外,还会平移),以便 (0, 0) 位于鼠标下方。此后,一切都按预期运行。
- 如果视图设置为“非交互式”,场景就会“跳跃”,使得每次滚轮事件发生时 (0, 0) 都位于鼠标下方。
有人能解释一下这种行为吗?我遗漏了什么吗?或者这是 Qt 中的一个错误?
我尝试在 python 3.12.4 下使用 PySide 6.7.2,并在 python 3.13.1 下使用 PySide 6.8.1(均在 Windows 上),结果相同。