2012-09-03 4 views
7

Ho alcune difficoltà con QGraphicsView e QGraphicsScene. Quando faccio zoom/zoom sulla scena e creo elementi con mousePressEvent, ho un offset nella posizione. Come può essere evitato?MousePressEvent, offset posizione in QGraphicsView

event.pos() sembra essere il problema ..

from PyQt4 import QtCore, QtGui 

class graphicsItem (QtGui.QGraphicsItem): 
    def __init__ (self): 
     super(graphicsItem, self).__init__() 
     self.rectF = QtCore.QRectF(0,0,10,10) 
    def boundingRect (self): 
     return self.rectF 
    def paint (self, painter=None, style=None, widget=None): 
     painter.fillRect(self.rectF, QtCore.Qt.red) 

class graphicsScene (QtGui.QGraphicsScene): 
    def __init__ (self, parent=None): 
     super (graphicsScene, self).__init__ (parent) 

class graphicsView (QtGui.QGraphicsView): 
    def __init__ (self, parent = None): 
     super (graphicsView, self).__init__ (parent) 
     self.parent = parent 
    def mousePressEvent(self, event): 
     super (graphicsView, self).mousePressEvent(event) 
     item = graphicsItem() 
     position = QtCore.QPointF(event.pos()) - item.rectF.center() 
     item.setPos(position.x() , position.y()) 
     self.parent.scene.addItem(item) 
    def wheelEvent (self, event): 
     super (graphicsView, self).wheelEvent(event) 
     factor = 1.2 
     if event.delta() < 0 : 
      factor = 1.0/factor 
     self.scale(factor, factor) 

class window (QtGui.QMainWindow): 
    def __init__ (self, parent = None) : 
     super (window, self).__init__(parent) 
     self.width = 800 
     self.height = 600 

     self.resize(self.width,self.height) 
     self.mainLayout = QtGui.QVBoxLayout(self) 

     self.view = graphicsView(self) 
     self.scene = graphicsScene(self) 
     self.view.setScene (self.scene) 

     factor = 1 
     self.scene.setSceneRect(0, 0, self.width * factor, self.height * factor) 
     self.view.setMinimumSize(self.width, self.height) 

     self.mainLayout.addWidget(self.view) 

    def show (self): 
     super (window, self).show() 

risposta

6

reimplementare mousePressEvent sulla scena, piuttosto che la vista.

In questo modo, l'argomento event sarà un QGraphicsSceneMouseEvent, che ha diverse utili funzioni aggiuntive - tra cui scenePos, che fa esattamente quello che vuoi:

class graphicsScene(QtGui.QGraphicsScene): 
    def __init__ (self, parent=None): 
     super(graphicsScene, self).__init__ (parent) 

    def mousePressEvent(self, event): 
     super(graphicsScene, self).mousePressEvent(event) 
     item = graphicsItem() 
     position = QtCore.QPointF(event.scenePos()) - item.rectF.center() 
     item.setPos(position.x() , position.y()) 
     self.addItem(item) 
+1

mi piace questa soluzione e lo uso io stesso. È un po 'come avere internamente un mousePressEvent nella vista grafica e quindi mapToScene la posizione del mouse. Ma questo è più elegante. – Trilarion