1

Я разрабатываю приложение, используя pyqt 4, поэтому, надеюсь, я делаю только ошибку новобранец.PyQt 4/Qt 4 move QGraphicsItem с помощью мыши с помощью специального обработчика событий

Я обнаружил, что не могу переместить QGraphicsItems и QGraphicsItemGroups в сцену, когда я использую собственные обработчики событий для mousePressEvent() и mouseMoveEvent().

Мое приложение позволяет мне рисовать произвольные фигуры, но я нажимаю модификатор ключа CTRL, чтобы установить обработчики событий, чтобы я мог выбирать объекты (и добавлять их в QGraphicsItemGroup) для перемещения всех выбранных объектов.

from PyQt4 import QtCore, QtGui 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 

class Window(QtGui.QWidget): 
def __init__(self): 
    QtGui.QWidget.__init__(self) 
    self.view = View(self) 
    layout = QtGui.QVBoxLayout(self) 
    layout.addWidget(self.view) 
    self.setMouseTracking(True) 
def __init__(self, parent): 
    QtGui.QGraphicsView.__init__(self, parent) 
    self.activeScene=QtGui.QGraphicsScene(self) 
    self.setScene(self.activeScene) 
    self.setInteractive(True) 
    self.setSceneRect(QtCore.QRectF(self.viewport().rect())) 
    self.startpos = None 
    self.endpos = None 
    self.multiSegmentLine = QtGui.QGraphicsItemGroup(scene=self.activeScene) 
    self.multiSegmentLine.setFlags(QtGui.QGraphicsItemGroup.ItemIsSelectable) 
    self.linePen=QPen(Qt.green, 3, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)   
    self.linesegment=QtGui.QGraphicsLineItem 

# Create a group of selected items to move as a group   
    self.createMoveGroup = QtGui.QGraphicsItemGroup(scene=self.activeScene) 
    self.createMoveGroup.setFlags(QtGui.QGraphicsItemGroup.ItemIsMovable) 
    # TESTING 
    self.boxxy = self.activeScene.addRect(10,10,100,100,self.linePen) 
    self.boxxy.setFlags(QtGui.QGraphicsItem.ItemIsMovable) 

# Booleans for state machine 
    self.stateNewLine=True  # Flag to determine line state True = new line, False = continuation of multisegment line 
    self.stateSelectItems=False # Flag to help determine True = item selection mode enabled, False = line drawing mode enabled 

# Create event handler 
def mousePressEvent(self, event):   
    if event.button()==QtCore.Qt.LeftButton: 
     # If CTRL key is not pressed then self.stateSelectItems is FALSE and 
     # mouse handling is normal 
     if self.stateSelectItems == False: 
      # New line has been started so no end point has been determined 
      if self.stateNewLine == True:   
      # Record starting position if creating a new line. This is used as 
      # origin for line drawn from start position to mouse tip. 
       self.startpos = QtCore.QPointF(self.mapToScene(event.pos())) 

      # The line is not new but rather is a multiple segment line. 
      elif self.stateNewLine == False: 
       # Update the length of the run    
       UserLineList.updateRunLength(self.linesegment.line()) 
       self.startpos = self.endpos    # Start new line at endpoint of previous segment 
       self.segmentCount = self.segmentCount+1  # increment segment count 
       #self.multiSegmentLine.setFlag(QtGui.QGraphicsItem.ItemIsMovable) 
       # Add line from starting position to location of mouse click 
       #self.linesegment=self.scene().addLine(QtCore.QLineF(self.startpos,self.endpos)) 
       self.linesegment = self.activeScene.addLine(QtCore.QLineF(self.startpos,self.endpos))     
       self.linesegment.setPen(self.linePen) 
       # Add newly created line to item group 
       self.multiSegmentLine.addToGroup(self.linesegment) 
       self.activeScene.addItem(self.multiSegmentLine) 
       self.activeScene.removeItem(self.linesegment) 

     # If CTRL key is pressed thenself.stateSelectItems == True and mouse 
     # handling has to change to support moving one or more screen items 
     elif self.stateSelectItems==True: 
      print("ENTERED MOVEMENT MODE!")     
      currentItem=self.activeScene.itemAt(self.mapToScene(event.pos()))    
      if currentItem != None: 
       self.createMoveGroup.addToGroup(currentItem) 
       self.stateSelectItems = True # set stateSelectItems flag to control mouse event handling 

def mouseDoubleClickEvent(self,event): 
#def mouseReleaseEvent(self, event): 
    if event.button() == QtCore.Qt.LeftButton: 
     self.startpos=None 
     self.stateNewLine=True # multisegment line has ended 
     # Create a record of the multisegment line 
     UserLineList.addMultiSegmentLine(self.multiSegmentLine) 

def mouseMoveEvent(self,event): 
    # If CTRL key is not pressed then self.stateSelectItems is FALSE and 
    # mouse handling is normal 
    if self.stateSelectItems == False: 
     # If this is a new line use start position at click 
     if self.stateNewLine == True: 
      self.endpos = QtCore.QPointF(self.mapToScene(event.pos()))   
      self.linesegment = self.activeScene.addLine(QtCore.QLineF(self.startpos,self.endpos))       
      self.linesegment.setPen(self.linePen) 
      self.stateNewLine = False         
     # If this line builds upon an existing segment 
     elif self.stateNewLine == False: 
      self.endpos = QtCore.QPointF(self.mapToScene(event.pos()))   
      self.scene().removeItem(self.linesegment)    
      self.linesegment = self.activeScene.addLine(QtCore.QLineF(self.startpos,self.endpos))    
      self.linesegment.setPen(self.linePen) 

    # If CTRL key is pressed thenself.stateSelectItems == True and mouse 
    # handling has to change to support moving one or more screen items   
    elif self.stateSelectItems == True: 
     self.createMoveGroup.mouseMoveEvent(self, event) 

def keyPressEvent(self,event): 
    keyModifier = QtGui.QApplication.keyboardModifiers() #Listen for keyboard modifier keys 
    if keyModifier == QtCore.Qt.ControlModifier: 
     print("keyEvent Control Key is pressed") 
     self.stateSelectItems=True 

def keyReleaseEvent(self,event):  
    keyModifier = QtGui.QApplication.keyboardModifiers() #Listen for keyboard modifier keys 
    if keyModifier == QtCore.Qt.ControlModifier: 
     self.stateSelectItems=False 
     self.createMoveGroup.ungrabMouse() # Selected items lose mouse grab 
     self.activeScene.destroyItemGroup(self.createMoveGroup) # Remove all selected items from move group 

if __name__ == '__main__': 
     import sys 
     app = QtGui.QApplication(sys.argv) 
     window = Window() 
     window.resize(640, 480) 
     window.show() 
     sys.exit(app.exec_()) 

ответ

0

Как и в ответ на this question, вы можете сделать вызов базового класса для того, чтобы сохранить существующую обработку событий соответствующего события. Например. в обработчике события нажатия кнопки мыши, нужно добавить следующую строку:

def mousePressEvent(self, event): 
    ... 
    super(Window, self).mousePressEvent(event) 
    ... 

Делайте это аналогичным образом для всех пользовательских обработчиков событий.