PyQt QGraphicsView使用变换矩阵进行平移和缩放

3

我试图使用QGraphics变换矩阵进行平移和缩放。缩放可以正常工作,但是平移参数m31和m32没有效果。看起来还有另一个函数会将场景居中。在下面的代码中,我操作rectScene以执行平移,但为什么不能使用m31和m32进行平移呢?(这是我的问题)

'''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()
1个回答

1

从数学角度来看,一切都运行得很好。你看不到变化的原因是因为QGraphicsView根据其alignment属性将视图居中。

来自Qt文档

QGraphicsView支持仿射变换,使用QTransform。您可以传递矩阵给setTransform(),也可以调用一个方便函数rotate()、scale()、translate()或shear()。最常见的两种变换是缩放,用于实现缩放,和旋转。QGraphicsView在变换期间保持视图中心固定。由于场景对齐(setAligment()),平移视图不会产生视觉影响。


好的,我查了一下Qt文档。你可以将对齐方式设置为居中、顶部、底部、左侧或右侧。是否有可能关闭此功能?或者你能否覆盖这个函数? - Ulf Wållgren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接