diff options
Diffstat (limited to 'src/main/python/utils')
-rw-r--r-- | src/main/python/utils/graphics.py | 109 |
1 files changed, 100 insertions, 9 deletions
diff --git a/src/main/python/utils/graphics.py b/src/main/python/utils/graphics.py index 80eb5e7..a4b3916 100644 --- a/src/main/python/utils/graphics.py +++ b/src/main/python/utils/graphics.py @@ -1,4 +1,7 @@ +from PyQt5 import QtCore, QtGui, QtWidgets +from PyQt5.QtCore import Qt, QRectF, QPointF from PyQt5.QtCore import Qt, QPointF, pyqtSignal +from PyQt5.QtWidgets import QGraphicsScene, QApplication from PyQt5.QtGui import QPen, QKeySequence, QTransform, QCursor from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QGraphicsProxyWidget, QGraphicsItem, QUndoStack, QAction, QUndoView @@ -73,16 +76,18 @@ class CustomView(QGraphicsView): temp = self.zoom self._zoom = value self.scale(self.zoom / temp, self.zoom / temp) - + class CustomScene(QGraphicsScene): """ Extends QGraphicsScene with undo-redo functionality """ labelAdded = pyqtSignal(shapes.QGraphicsItem) - + itemMoved = QtCore.pyqtSignal(QtWidgets.QGraphicsItem, QtCore.QPointF) + def __init__(self, *args, parent=None): super(CustomScene, self).__init__(*args, parent=parent) - + self.movingItems = [] # List to store selected items for moving + self.oldPositions = {} # Dictionary to store old positions of moved items self.undoStack = QUndoStack(self) #Used to store undo-redo moves self.createActions() #creates necessary actions that need to be called for undo-redo @@ -91,12 +96,12 @@ class CustomScene(QGraphicsScene): self.deleteAction = QAction("Delete Item", self) self.deleteAction.setShortcut(Qt.Key_Delete) self.deleteAction.triggered.connect(self.deleteItem) - + self.undoAction = self.undoStack.createUndoAction(self, "Undo") self.undoAction.setShortcut(QKeySequence.Undo) self.redoAction = self.undoStack.createRedoAction(self, "Redo") self.redoAction.setShortcut(QKeySequence.Redo) - + def createUndoView(self, parent): # creates an undo stack view for current QGraphicsScene undoView = QUndoView(self.undoStack, parent) @@ -115,17 +120,101 @@ class CustomScene(QGraphicsScene): self.count+=1 self.undoStack.push(deleteCommand(j, self)) self.undoStack.push(deleteCommand(itemToDelete, self)) - + def itemMoved(self, movedItem, lastPos): #item move event, checks if item is moved self.undoStack.push(moveCommand(movedItem, lastPos)) self.advance() - + def addItemPlus(self, item): # extended add item method, so that a corresponding undo action is also pushed self.undoStack.push(addCommand(item, self)) - + def mousePressEvent(self, event): + bdsp = event.buttonDownScenePos(Qt.LeftButton) # Get click position + point = QPointF(bdsp.x(), bdsp.y()) # Create a QPointF from click position + itemList = self.items(point) # Get items at the specified point + if itemList: + item = itemList[0] # Select the first item in the list + if event.button() == Qt.LeftButton: + modifiers = QApplication.keyboardModifiers() + if modifiers == Qt.ControlModifier: + # Ctrl key is pressed, add item to the moving items list + if item not in self.movingItems: + self.movingItems.append(item) + self.oldPositions[item] = item.pos() + else: + # Ctrl key is not pressed, clear the moving items list and selection + self.movingItems.clear() + self.clearSelection() + item.setSelected(True) + + return super(CustomScene, self).mousePressEvent(event) + + + def mouseReleaseEvent(self, event): + if event.button() == QtCore.Qt.LeftButton: + for item in self.movingItems: + if self.oldPositions[item] != item.pos(): + # Item position has changed, invoke the callback function + self.itemMoved(item, self.oldPositions[item]) + self.movingItems.clear() # Clear the moving items list + self.oldPositions.clear() # Clear the old positions dictionary + + return super(CustomScene, self).mouseReleaseEvent(event) + + + def mouseMoveEvent(self, mouseEvent): + if self.movingItems: + # Move all selected items together + for item in self.movingItems: + newPos = item.pos() + mouseEvent.scenePos() - mouseEvent.lastScenePos() + item.setPos(newPos) + + item = self.itemAt(mouseEvent.scenePos().x(), mouseEvent.scenePos().y(), QTransform()) + if isinstance(item, shapes.SizeGripItem): + item.parentItem().showLineGripItem() + + return super(CustomScene, self).mouseMoveEvent(mouseEvent) + + # The above is the mouse events for moving multiple images at once. + + """def mousePressEvent(self, event): + bdsp = event.buttonDownScenePos(Qt.LeftButton) # get click pos + point = QPointF(bdsp.x(), bdsp.y()) # create a QPointF from click pos + itemList = self.items(point) # get items at said point + if event.button() == Qt.LeftButton: + if itemList: + self.movingItems = itemList + self.initialPositions = {} + for item in self.movingItems: + self.initialPositions[item] = item.pos() + else: + self.movingItems = [] + self.clearSelection() + return super(CustomScene, self).mousePressEvent(event) + + def mouseMoveEvent(self, event): + if event.buttons() == Qt.LeftButton and self.movingItems: + modifiers = QApplication.keyboardModifiers() + if modifiers == Qt.ControlModifier: + for item in self.movingItems: + item.setPos(item.pos() + event.scenePos() - event.lastScenePos()) + else: + super(CustomScene, self).mouseMoveEvent(event) + + def mouseReleaseEvent(self, event): + if event.button() == Qt.LeftButton and self.movingItems: + for item in self.movingItems: + if item.pos() != self.initialPositions[item]: + self.itemMoved(item, self.initialPositions[item]) + self.movingItems = [] + self.initialPositions = {} + return super(CustomScene, self).mouseReleaseEvent(event)""" + + # The above mouse events are for moving items on top of each other. + + """def mousePressEvent(self, event): # overloaded mouse press event to check if an item was moved bdsp = event.buttonDownScenePos(Qt.LeftButton) #get click pos point = QPointF(bdsp.x(), bdsp.y()) #create a Qpoint from click pos @@ -150,7 +239,9 @@ class CustomScene(QGraphicsScene): QTransform()) if isinstance(item,shapes.SizeGripItem): item.parentItem().showLineGripItem() - super(CustomScene,self).mouseMoveEvent(mouseEvent) + super(CustomScene,self).mouseMoveEvent(mouseEvent)""" + + # The above is the original mouse events def reInsertLines(self): currentIndex = self.undoStack.index() |