PyQt / PySide QGraphicsView无法翻译

时间:2017-11-29 22:14:42

标签: python qt pyqt pyside

我想将Python-Qt QGraphicsView对象子类化以显示一些图像,我希望能够通过鼠标拖动进行平移。但是,方法QGraphicsView.translate(x,y)QGraphicsView.CenterOn(x,y)不起作用。这是一个简单的示例代码片段(为简单起见,我遗漏了mouseMoveEvent):

import sys
from qtpy import QtGui, QtCore, QtWidgets

class MyView(QtWidgets.QGraphicsView):
    def __init__(self):
        QtWidgets.QGraphicsView.__init__(self)

        self.scene = QtWidgets.QGraphicsScene(self)
        self.item = QtWidgets.QGraphicsEllipseItem(-20, -10, 160, 160)
        self.scene.addItem(self.item)
        self.setScene(self.scene)
        self._drag = False
        self._pos = QtCore.QPointF(0.0, 0.0)

    def wheelEvent(self, event):
        if event.angleDelta().y() > 0:
            self.scale(1.5,1.5)   # Increase zoom
        else:
            self.scale(0.75,0.75) # Decrease zoom

    def mousePressEvent(self, event):
        self._drag = True
        self._pos = event.pos()

    def mouseReleaseEvent(self, event):
        if self._drag:
            self._drag = False
            newPos = event.pos()
            delta = self._pos - newPos
            # What the docs say work to translate:
            self.translate( delta.x(), delta.y() )

            aff = self.transform()
            print( 'isTranslating: {}, dx: {}, dy: {}'.format(aff.isTranslating(), aff.dx(), aff.dy()) )
            print( 'hozScroll: {}, vertScroll: {}'.format( self.horizontalScrollBar().value(), self.verticalScrollBar().value() ) )


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    view = MyView()
    view.show()
    sys.exit(app.exec_())

如果需要,将PySide2PyQt5替换为qtpy。要启用翻译,首先必须使用鼠标滚轮滚动。然后你尝试拖动你可以看到,虽然转换变换矩阵正在改变,但视图不会翻译。

1 个答案:

答案 0 :(得分:1)

因为QGraphicsView:

http://pyside.github.io/docs/pyside/PySide/QtGui/QGraphicsView.html

是QAbstractScrollArea的子类:

http://pyside.github.io/docs/pyside/PySide/QtGui/QAbstractScrollArea.html

QGraphicsView.translate()会移动场景,但随后会调用父类,并且连接到滚动条的信号会将场景移回滚动条指示的位置。一种解决方案是关闭滚动条信号:

self.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff )
self.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff )
self.horizontalScrollBar().disconnect()
self.verticalScrollBar().disconnect()

如果要保留滚动条,则必须直接设置它们:

self.horizontalScrollBar().setValue( self.horizontalScrollBar().value() + delta.x() )
self.verticalScrollBar().setValue( self.verticalScrollBar().value() + delta.y() )

或者你可能会重新插入进入它们的信号/插槽。