程序化滚动QGraphicsView
我想在我的(Py)Qt 应用程序中的 QGraphicsView 上实现一个滚动/平移的功能。这个功能应该是这样的:用户按下中间鼠标键,然后在移动鼠标时,视图会跟着滚动(这个功能其实很常见)。
我尝试使用 QWidget 继承来的 scroll() 方法。但是,这个方法似乎是移动了整个视图,包括滚动条。请看图片。
所以,既然这不是我应该使用的方法,那我该怎么做呢?或者说这其实是正确的方法,但我做错了什么?我使用的代码是:
def __init__(self):
...
self.ui.imageArea.mousePressEvent=self.evImagePress
self.ui.imageArea.mouseMoveEvent=self.evMouseMove
self.scrollOnMove=False
self.scrollOrigin=[]
...
def evImagePress(self, event):
if event.button() == Qt.LeftButton:
self.evImageLeftClick(event)
if event.button() == Qt.MidButton:
self.scrollOnMove=not self.scrollOnMove
if self.scrollOnMove:
self.scrollOrigin=[event.x(), event.y()]
...
def evMouseMove(self, event):
if self.scrollOnMove:
self.ui.imageArea.scroll(event.x()-self.scrollOrigin[0],
event.y()-self.scrollOrigin[1])
它的表现和我预期的一样,除了整个移动小部件的事情。
4 个回答
1
denis给出的答案是正确的,可以让翻译功能正常工作。PF4Public的评论也很有道理:这可能会影响缩放。我的解决办法和PF4Public的不一样——我不是使用mapToScene,而是保留锚点,然后在翻译后再恢复它:
previousAnchor = view.transformationAnchor()
#have to set this for self.translate() to work.
view.setTransformationAnchor(QGraphicsView.NoAnchor)
view.translate(x_diff,y_diff)
#have to reset the anchor or scaling (zoom) stops working:
view.setTransformationAnchor(previousAnchor)
4
我对translate()方法的补充说明。这个方法很好用,除非你对场景进行了缩放。如果你缩放了场景,你会发现图像和鼠标的移动不同步。这时候,mapToScene()就派上用场了。你需要把鼠标事件中的点转换成场景坐标。然后,把转换后的差值传给translate(),这样一来,你的场景就能非常精准地跟随鼠标移动了。
举个例子:
QPointF tmp2 = mapToScene(event->pos());
QPointF tmp = tmp2.mapToScene(previous_point);
translate(tmp.x(),tmp.y());
3
我自己没有做过这个,但这是来自于QGraphicsView
的文档内容。
... 当场景的大小超过滚动条的范围时,你可以选择使用translate()来浏览场景。
使用scroll
是在移动这个小部件,而translate
可以帮助你实现想要的效果,就是在视图下移动QGraphicsScene
的内容。