Reputation: 171
I am trying to do pan and zoom with the QGraphics transform matrix. The zoom works fin but the pan parameters m31 and m32 have no effect. It looks like there is an another function that centers the scene. In the code below I manipulate the rectScene to do Pan but why can I not use m31 and m32 to Pan? (This is my question
'''Pan (left mouse but) and zoom (mouse wheel) test'''
'''Python 3.4 (No differance between PyQt4 and PyQt5)'''
#from PyQt5 import QtGui, QtCore
#import PyQt5.QtWidget as QW
from PyQt4 import QtGui, QtCore
import PyQt4.QtGui as QW
import numpy as np
class ZoomAndPan(QW.QGraphicsView):
def __init__(self,parent=None):
super(ZoomAndPan,self).__init__(parent)
self.setWindowTitle('ZoomAndPan')
self.setGeometry(600,300,600,400)
'Left button in top of image. Shows the transform matrix (press to reset)'
self.mess = QW.QPushButton('Transform Matrix\n\n\ndx,xy\ncounter', self)
self.mess.clicked.connect(self.resetM)
'm31 button, adds 200 to m31'
self.m31 = QW.QPushButton('m31', self)
self.m31.move(200,0)
self.m31.clicked.connect(self.addM31)
'm13 button, adds 0.0001 to m13'
self.m13 = QW.QPushButton('m13', self)
self.m13.move(300,0)
self.m13.clicked.connect(self.addM13)
self.count=0 #Counter
# Create scene
self.sc=scene(self,self)
self.setScene(self.sc)
def mouseMoveEvent(self,event):
'Pan by manipulting sceneRect'
pos=event.pos()
pos=self.mapToScene(pos)
dx=pos.x()-self.sc.startPos.x()
dy=pos.y()-self.sc.startPos.y()
rect=self.sceneRect().getRect()
self.setSceneRect(rect[0]-dx,rect[1]-dy,rect[2],rect[3])
# Increas counter to show that the loop works
self.count+=1
self.showMatrix()
def showMatrix(self):
'Show matrix in Textbox (Buttton)'
m=self.transform()
str1='{0:5.2f}{1:5.2f} {2:6.4f}\n'.format(m.m11(), m.m12(),m.m13())
str2='{0:5.2f}{1:5.2f}{2:5.2f}\n'.format(m.m21(), m.m22(),m.m23())
str3='{0:5.2f}{1:5.2f}{2:5.2f}\n'.format(m.m31(), m.m32(),m.m33())
str4='{0:5.2f}{1:5.2f}\n'.format(m.dx(), m.dy(),m.m33())
'Show counter '
str5='{0:5.0f}'.format(self.count)
self.mess.setText(str1+str2+str3+str4+str5)
def resetM(self):
'Reset transform'
self.resetTransform()
self.showMatrix()
def addM31(self):
'Add 200 to m31 '
m=self.transform()
m.setMatrix(m.m11(),m.m12(),m.m13(),m.m21(),m.m22(),m.m23(),m.m31()+200,m.m32(),m.m33())
self.setTransform(m)
self.showMatrix()
def addM13(self):
'Add 0.0001 to m13 '
m=self.transform()
m.setMatrix(m.m11(),m.m12(),m.m13()+0.0001,m.m21(),m.m22(),m.m23(),
m.m31(),m.m32(),m.m33())
self.setTransform(m)
self.showMatrix()
class scene(QW.QGraphicsScene):
def __init__(self,parent,myView=[]):
QW.QGraphicsScene.__init__(self,parent)
self.myView=myView
# Some items in scene
self.txt=self.addSimpleText("///////")
self.txt.setPos(2,-20)
self.txt.setScale(2)
self.txt.setBrush(QtGui.QBrush(QtCore.Qt.green))
self.addRect(0,16,20,20, pen=QtGui.QPen(QtCore.Qt.blue))
self.addRect(10,60,32,8, pen=QtGui.QPen(QtCore.Qt.red))
self.addRect(30,16,20,20, pen=QtGui.QPen(QtCore.Qt.blue))
self.N=0
def mousePressEvent(self, event):
self.myView.setDragMode(1) # Works fine without this
self.startPos=event.scenePos()
def mouseReleaseEvent(self, event):
self.myView.setDragMode(0)
def wheelEvent(self, event):
'zoom'
sc=event.delta()/100
if sc<0: sc=-1/sc
self.myView.scale(sc,sc)
self.myView.setDragMode(0)
self.myView.showMatrix()
def main():
app = QW.QApplication([])
fig=ZoomAndPan()
fig.show();
app.exec_()
if __name__=='__main__':
main()
Upvotes: 3
Views: 3834
Reputation: 5000
From a mathematical point of view everything is working fine. The reason you see no changes is because QGraphicsView
centers the view according to its alignment
property.
From the Qt docs:
QGraphicsView supports affine transformations, using QTransform. You can either pass a matrix to setTransform(), or you can call one of the convenience functions rotate(), scale(), translate() or shear(). The most two common transformations are scaling, which is used to implement zooming, and rotation. QGraphicsView keeps the center of the view fixed during a transformation. Because of the scene alignment (setAligment()), translating the view will have no visual impact.
Upvotes: 2