From 2917912f54c26ccfca010f6fc09f75425fa3a2df Mon Sep 17 00:00:00 2001 From: Sumit-Sahu Date: Mon, 18 May 2020 20:36:18 +0530 Subject: Rename shapes.py to src/main/python/shapes/shapes.py --- src/main/python/shapes/shapes.py | 475 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 475 insertions(+) create mode 100644 src/main/python/shapes/shapes.py (limited to 'src/main/python/shapes/shapes.py') diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py new file mode 100644 index 0000000..482088f --- /dev/null +++ b/src/main/python/shapes/shapes.py @@ -0,0 +1,475 @@ +import random + +from PyQt5 import QtCore +from PyQt5.QtSvg import QGraphicsSvgItem, QSvgRenderer +from PyQt5.QtWidgets import QLineEdit, QGraphicsItem, QGraphicsEllipseItem, QGraphicsProxyWidget, QGraphicsPathItem, \ + QGraphicsSceneHoverEvent, QGraphicsColorizeEffect +from PyQt5.QtGui import QPen, QColor, QFont, QCursor, QPainterPath, QPainter, QDrag, QBrush, QImage +from PyQt5.QtCore import Qt, QRectF, QPointF, QSizeF, QEvent, QMimeData, QFile, QIODevice, QRect +from PyQt5.QtXml import QDomDocument +from PyQt5.uic.properties import QtGui, QtWidgets +from xml.dom import minidom +import re + +from line import Line +from svghandler import SvgHandler + + +class GripItem(QGraphicsPathItem): + """ + Extends PyQt5's QGraphicsPathItem to create the general structure of the Grabbable points for resizing shapes. + Takes two parameters, reference item (On which the grip items are to appear) and the grip index + """ + def __init__(self, annotation_item, path, parent=None): + """ + Extends PyQt5's QGraphicsPathItem to create the general structure of the Grabbable points for resizing shapes. + """ + QGraphicsPathItem.__init__(self, parent) + self.m_annotation_item = annotation_item + # self.m_index = index + + self.setPath(path) + + self.setAcceptHoverEvents(True) + self.setCursor(QCursor(Qt.PointingHandCursor)) + # self.setVisible(False) + + # def hoverEnterEvent(self, event): + # """ + # defines shape highlighting on Mouse Over + # """ + # self.setPen(QPen(QColor("black"), 2)) + # self.setBrush(QColor("red")) + # super(GripItem, self).hoverEnterEvent(event) + # + # def hoverLeaveEvent(self, event): + # """ + # defines shape highlighting on Mouse Leave + # """ + # self.setPen(QPen(Qt.transparent)) + # self.setBrush(Qt.transparent) + # super(GripItem, self).hoverLeaveEvent(event) + + def mouseReleaseEvent(self, event): + """ + Automatically deselects grip item on mouse release + """ + self.setSelected(False) + super(GripItem, self).mouseReleaseEvent(event) + + # def itemChange(self, change, value): + # """ + # Calls movepoint from reference item, with the index of this grip item + # """ + # if change == QGraphicsItem.ItemPositionChange and self.isEnabled(): + # self.m_annotation_item.movePoint(self.m_index, value) + # return super(GripItem, self).itemChange(change, value) + + +class SizeGripItem(GripItem): + """ + Extends grip items for vertical and horizontal directions, with hover events and directional changes + """ + + def __init__(self, annotation_item, index, direction=Qt.Horizontal, parent=None): + self.width = self.height = 0 + if direction is Qt.Horizontal: + self.height = annotation_item.boundingRect().height() + else: + self.width = annotation_item.boundingRect().width() + + path = QPainterPath() + path.addRect(QRectF(0, 0, self.width, self.height)) + super(SizeGripItem, self).__init__(annotation_item, path=path, parent=parent) + self.setFlag(QGraphicsItem.ItemIsSelectable, True) + self.setFlag(QGraphicsItem.ItemIsMovable, True) + self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) + self.setPen(QPen(QColor("black"), -1)) + self.setZValue(2) + self._direction = direction + self.m_index = index + + @property + def direction(self): + """ + property that returns the current intended resize direction of the grip item object + """ + return self._direction + + def update_path(self): + if self._direction is Qt.Horizontal: + self.height = self.m_annotation_item.boundingRect().height() + else: + self.width = self.m_annotation_item.boundingRect().width() + path = QPainterPath() + path.addRect(QRectF(0, 0, self.width, self.height)) + self.setPath(path) + + def update_position(self): + """updates grip items + """ + self.update_path() + pos = self.m_annotation_item.mapToScene(self.point(self.m_index)) + x = self.m_annotation_item.boundingRect().x() + y = self.m_annotation_item.boundingRect().y() + pos.setX(pos.x() + x) + pos.setY(pos.y() + y) + self.setEnabled(False) + self.setPos(pos) + self.setEnabled(True) + + def point(self, index): + """ + yields a list of positions of grip items in a node item + """ + x = self.m_annotation_item.boundingRect().width() + y = self.m_annotation_item.boundingRect().height() + if 0 <= index < 4: + return [ + QPointF(0, 0), + QPointF(0, 0), + QPointF(0, y), + QPointF(x, 0) + ][index] + + def hoverEnterEvent(self, event): + """ + Changes cursor to horizontal resize or vertical resize depending on the direction of the grip item on mouse enter + """ + self.setPen(QPen(QColor("black"), 2)) + self.setBrush(QColor("red")) + # self.setVisible(True) + if self._direction == Qt.Horizontal: + self.setCursor(QCursor(Qt.SizeHorCursor)) + else: + self.setCursor(QCursor(Qt.SizeVerCursor)) + super(SizeGripItem, self).hoverEnterEvent(event) + + def hoverLeaveEvent(self, event): + """ + reverts cursor to default on mouse leave + """ + # self.setVisible(False) + self.setPen(QPen(Qt.transparent)) + self.setBrush(Qt.transparent) + self.setCursor(QCursor(Qt.ArrowCursor)) + super(SizeGripItem, self).hoverLeaveEvent(event) + + def itemChange(self, change, value): + """ + Moves position of grip item on resize or reference circle's position change + """ + + if change == QGraphicsItem.ItemPositionChange and self.isEnabled(): + p = QPointF(self.pos()) + if self.direction == Qt.Horizontal: + p.setX(value.x()) + elif self.direction == Qt.Vertical: + p.setY(value.y()) + self.m_annotation_item.resize(self.m_index, p) + return p + return super(SizeGripItem, self).itemChange(change, value) + + def removeFromCanvas(self): + if self.scene(): + self.scene().removeItem(self) + + +class LineGripItem(GripItem): + circle = QPainterPath() + circle.addEllipse(QRectF(-10, -10, 20, 20)) + def __init__(self, annotation_item, index, parent=None): + """ + Extends grip items for connecting lines , with hover events and mouse events + """ + self.path = LineGripItem.circle + super(LineGripItem, self).__init__(annotation_item,path=self.path, parent=parent) + self.m_index = index + self.connectedLines = [] + self.tempLine = None + self.previousHoveredItem = None + self.setFlag(QGraphicsItem.ItemIsSelectable, True) + # self.setZValue(2) + self.setPen(QPen(QColor("black"), -1)) + # self.setBrush(QColor("red")) + # self.setVisible(False) + + def point(self, index): + """ + yields a list of positions of grip items in a node item + """ + radiusOfGripItem = self.boundingRect().width() / 2 + x = self.m_annotation_item.boundingRect().width() + y = self.m_annotation_item.boundingRect().height() + if 0 <= index < 4: + return [ + QPointF(x / 2, 0), + QPointF(0, y / 2), + QPointF(x / 2, y), + QPointF(x, y / 2) + ][index] + + def update_position(self): + # print('updating grip item ', self.m_index) + pos = self.point(self.m_index) + x = self.m_annotation_item.boundingRect().x() + y = self.m_annotation_item.boundingRect().y() + pos.setX(pos.x() + x) + pos.setY(pos.y() + y) + self.setEnabled(False) + self.setPos(pos) + self.setEnabled(True) + for line in self.connectedLines: + line.updateLine() + + def mousePressEvent(self, mouseEvent): + if mouseEvent.button() != Qt.LeftButton: + return + radiusOfGripItem = self.boundingRect().width() / 2 + startPoint = endPoint = self.parentItem().mapToScene(self.pos()) + + self.tempLine = Line(startPoint, endPoint) + self.scene().addItem(self.tempLine) + super().mousePressEvent(mouseEvent) + + def mouseMoveEvent(self, mouseEvent): + if self.tempLine: + endPoint = mouseEvent.scenePos() + self.tempLine.updateLine(endPoint=endPoint) + super().mouseMoveEvent(mouseEvent) + item = self.scene().itemAt(mouseEvent.scenePos().x(), mouseEvent.scenePos().y(), + self.m_annotation_item.transform()) + # print(self.m_annotation_item.transform()) + + if self.previousHoveredItem and item != self.previousHoveredItem and \ + item not in self.previousHoveredItem.lineGripItems: + self.previousHoveredItem.hideGripItem() + + if type(item) == NodeItem: + self.previousHoveredItem = item + item.showGripItem() + + def mouseReleaseEvent(self, mouseEvent): + if self.tempLine: + item = self.scene().itemAt(mouseEvent.scenePos().x(), mouseEvent.scenePos().y(), + self.transform()) + if type(item) == LineGripItem: + endPoint = item.parentItem().mapToScene(item.pos()) + self.tempLine.updateLine(endPoint=endPoint) + self.connectedLines.append(self.tempLine) + item.connectedLines.append(self.tempLine) + self.tempLine.setStartGripItem(self) + self.tempLine.setEndGripItem(item) + + else: + self.scene().removeItem(self.tempLine) + super().mouseReleaseEvent(mouseEvent) + self.tempLine = None + self.previousHoveredItem = None + + def removeConnectedLines(self): + for line in self.connectedLines: + line.removeFromCanvas() + + def show(self): + self.setPen(QPen(QColor("black"), 2)) + self.setBrush(QColor("red")) + + def hide(self): + if (self.parentItem().isSelected() or self.isSelected()) is False: + self.setPen(QPen(Qt.transparent)) + self.setBrush(Qt.transparent) + + +class NodeItem(QGraphicsSvgItem): + + def __init__(self, unitOpType, parent=None): + QGraphicsSvgItem.__init__(self, parent) + self.m_renderer = QSvgRenderer() + self.type = unitOpType + + + self.file = QFile("svg/" + "Boiler" + ".svg") + if not self.file.open(QIODevice.ReadOnly): + print("Cannot open the file") + exit(-1) + self.svghandler = SvgHandler(self.file) + self.updateRenderer() + self.rect = QRectF(0,0,300,400) + # self.rect=QRectF(0,0,self.m_renderer.defaultSize().width(),self.m_renderer.defaultSize().height()) + # self.rect = self.m_renderer.viewBoxF() + # self.changeColour("red") + # self.changeStrokeWidth(4) + + self.setZValue(2) + self.setAcceptHoverEvents(True) + self.setAcceptDrops(True) + self.setFlags(QGraphicsSvgItem.ItemIsMovable | + QGraphicsSvgItem.ItemIsSelectable | + QGraphicsSvgItem.ItemSendsGeometryChanges) + + self.lineGripItems = [] + self.sizeGripItems = [] + self.ds= 0.70875001 + self.cs = 0.70875001 + self.dw=self.m_renderer.defaultSize().width() + self.dh=self.m_renderer.defaultSize().height() + self.vdw = self.m_renderer.viewBoxF().width() + self.vdh=self.m_renderer.viewBoxF().height() + + + def changeStrokeWidth(self,value): + self.svghandler.setStrokeWidth(value) + self.updateRenderer() + + def changeColour(self,value): + self.svghandler.setColor(value) + self.updateRenderer() + """graphics effect can also used to change colour of an svg image + """ + # self._effect = QGraphicsColorizeEffect() + # self._effect.setColor(Qt.red) + # self._effect.setStrength(1) + # self.setGraphicsEffect(self._effect) + + def updateRenderer(self): + byteArray = self.svghandler.doc.toByteArray() + self.m_renderer.load(byteArray) + self.setSharedRenderer(self.m_renderer) + + def boundingRect(self): + return self.rect + + def paint(self, painter, option, widget): + if not self.m_renderer: + QGraphicsSvgItem.paint(self, painter, option, widget) + self.m_renderer.render(painter, self.boundingRect()) + + def update_rect(self): + """Update rect of node item + """ + self.prepareGeometryChange() + self.update(self.rect) + + def resize(self, i, p): + """Move grip item with changing rect of node item + """ + x = self.boundingRect().x() + y = self.boundingRect().y() + width = self.boundingRect().width() + height = self.boundingRect().height() + p_new = self.sizeGripItems[i].pos() + self.prepareGeometryChange() + + if i == 0 or i == 1: + self.rect = QRectF(x + p.x() - p_new.x(), y + p.y() - p_new.y(), width - p.x() + p_new.x(), + height - p.y() + p_new.y()) + + if i == 2 or i == 3: + self.rect = QRectF(x, y, width + p.x() - p_new.x(), height + p.y() - p_new.y()) + + self.cs = self.ds*(self.boundingRect().width()/self.vdw) + # self.cs =self.s + print(self.boundingRect()) + print(self.cs) + offset = (self.cs-self.ds) + offset = offset*(self.vdw/self.boundingRect().width()) + # self.m_renderer.setViewBox(QRectF(offset/2.0,0,self.vdw-offset,self.vdh)) + + # self.update_rect() + self.updateSizeGripItem([i]) + self.updateLineGripItem() + + def addGripItem(self): + """adds grip items + """ + if self.scene() and not self.lineGripItems: + for i, (direction) in enumerate( + ( + Qt.Vertical, + Qt.Horizontal, + Qt.Vertical, + Qt.Horizontal, + ) + ): + item = LineGripItem(self, i) + item.setParentItem(self) + self.scene().addItem(item) + self.lineGripItems.append(item) + item = SizeGripItem(self, i, direction) + self.scene().addItem(item) + self.sizeGripItems.append(item) + + def updateLineGripItem(self, index_no_updates=None): + # index_no_updates = index_no_updates or [] + for item in self.lineGripItems: + item.update_position() + + def updateSizeGripItem(self, index_no_updates=None): + """updates grip items + """ + index_no_updates = index_no_updates or [] + for i, item in zip(range(len(self.sizeGripItems)), self.sizeGripItems): + if i not in index_no_updates: + item.update_position() + + def itemChange(self, change, value): + """Overloads and extends QGraphicsSvgItem to also update gripitem + """ + if change == QGraphicsItem.ItemPositionHasChanged: + self.updateLineGripItem() + self.updateSizeGripItem() + return + if change == QGraphicsItem.ItemSceneHasChanged: + self.addGripItem() + self.updateLineGripItem() + self.updateSizeGripItem() + return + return super(NodeItem, self).itemChange(change, value) + + def addOnCanvas(self, scene): + """This function is used to add Node Item on canvas + :return: + """ + scene.addItem(self) + + def removeFromCanvas(self): + """This function is used to remove item from canvas + :return: + """ + for item in self.lineGripItems: + item.removeConnectedLines() + for item in self.sizeGripItems: + item.removeFromCanvas() + self.scene().removeItem(self) + + def hoverEnterEvent(self, event): + """defines shape highlighting on Mouse Over + """ + self.showGripItem() + super(NodeItem, self).hoverEnterEvent(event) + + def hoverLeaveEvent(self, event): + """defines shape highlighting on Mouse Leave + """ + # if self.isSelected() is False: + self.hideGripItem() + super(NodeItem, self).hoverLeaveEvent(event) + + def showGripItem(self): + for item in self.lineGripItems: + item.setPen(QPen(QColor("black"), 2)) + item.setBrush(QColor("red")) + for item in self.sizeGripItems: + item.setPen(QPen(QColor("black"), 2)) + # item.setBrush(QColor("red")) + + def hideGripItem(self): + for item in self.lineGripItems: + if item.isSelected() is False: + item.setPen(QPen(Qt.transparent)) + item.setBrush(Qt.transparent) + for item in self.sizeGripItems: + item.setPen(QPen(Qt.transparent)) + item.setBrush(Qt.transparent) + -- cgit From 0e8a9866a7101233820273e9d97598af31382ef0 Mon Sep 17 00:00:00 2001 From: sumit Date: Tue, 19 May 2020 20:21:05 +0530 Subject: clean up and add comments --- src/main/python/shapes/shapes.py | 238 +++++++++++++++++---------------------- 1 file changed, 103 insertions(+), 135 deletions(-) (limited to 'src/main/python/shapes/shapes.py') diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py index 482088f..982e882 100644 --- a/src/main/python/shapes/shapes.py +++ b/src/main/python/shapes/shapes.py @@ -1,38 +1,29 @@ -import random - -from PyQt5 import QtCore +from PyQt5 import QtCore, QtWidgets from PyQt5.QtSvg import QGraphicsSvgItem, QSvgRenderer from PyQt5.QtWidgets import QLineEdit, QGraphicsItem, QGraphicsEllipseItem, QGraphicsProxyWidget, QGraphicsPathItem, \ QGraphicsSceneHoverEvent, QGraphicsColorizeEffect from PyQt5.QtGui import QPen, QColor, QFont, QCursor, QPainterPath, QPainter, QDrag, QBrush, QImage from PyQt5.QtCore import Qt, QRectF, QPointF, QSizeF, QEvent, QMimeData, QFile, QIODevice, QRect -from PyQt5.QtXml import QDomDocument -from PyQt5.uic.properties import QtGui, QtWidgets -from xml.dom import minidom -import re from line import Line -from svghandler import SvgHandler class GripItem(QGraphicsPathItem): """ - Extends PyQt5's QGraphicsPathItem to create the general structure of the Grabbable points for resizing shapes. - Takes two parameters, reference item (On which the grip items are to appear) and the grip index + Extends QGraphicsPathItem to create the structure of the Grabbable points for resizing shapes and connecting lines. + Takes two parameters, reference item (On which the grip items are to appear) and the path of the item """ + def __init__(self, annotation_item, path, parent=None): """ Extends PyQt5's QGraphicsPathItem to create the general structure of the Grabbable points for resizing shapes. """ QGraphicsPathItem.__init__(self, parent) self.m_annotation_item = annotation_item - # self.m_index = index - + # set path of item self.setPath(path) - self.setAcceptHoverEvents(True) self.setCursor(QCursor(Qt.PointingHandCursor)) - # self.setVisible(False) # def hoverEnterEvent(self, event): # """ @@ -57,15 +48,6 @@ class GripItem(QGraphicsPathItem): self.setSelected(False) super(GripItem, self).mouseReleaseEvent(event) - # def itemChange(self, change, value): - # """ - # Calls movepoint from reference item, with the index of this grip item - # """ - # if change == QGraphicsItem.ItemPositionChange and self.isEnabled(): - # self.m_annotation_item.movePoint(self.m_index, value) - # return super(GripItem, self).itemChange(change, value) - - class SizeGripItem(GripItem): """ Extends grip items for vertical and horizontal directions, with hover events and directional changes @@ -96,7 +78,9 @@ class SizeGripItem(GripItem): """ return self._direction - def update_path(self): + def updatePath(self): + """updates path of size grip item + """ if self._direction is Qt.Horizontal: self.height = self.m_annotation_item.boundingRect().height() else: @@ -105,10 +89,10 @@ class SizeGripItem(GripItem): path.addRect(QRectF(0, 0, self.width, self.height)) self.setPath(path) - def update_position(self): - """updates grip items + def updatePosition(self): + """updates position of grip items """ - self.update_path() + self.updatePath() pos = self.m_annotation_item.mapToScene(self.point(self.m_index)) x = self.m_annotation_item.boundingRect().x() y = self.m_annotation_item.boundingRect().y() @@ -136,9 +120,8 @@ class SizeGripItem(GripItem): """ Changes cursor to horizontal resize or vertical resize depending on the direction of the grip item on mouse enter """ - self.setPen(QPen(QColor("black"), 2)) - self.setBrush(QColor("red")) - # self.setVisible(True) + # self.setPen(QPen(QColor("black"), 2)) + # self.setBrush(QColor("red")) if self._direction == Qt.Horizontal: self.setCursor(QCursor(Qt.SizeHorCursor)) else: @@ -149,17 +132,15 @@ class SizeGripItem(GripItem): """ reverts cursor to default on mouse leave """ - # self.setVisible(False) - self.setPen(QPen(Qt.transparent)) - self.setBrush(Qt.transparent) + # self.setPen(QPen(Qt.transparent)) + # self.setBrush(Qt.transparent) self.setCursor(QCursor(Qt.ArrowCursor)) super(SizeGripItem, self).hoverLeaveEvent(event) def itemChange(self, change, value): """ - Moves position of grip item on resize or reference circle's position change + Moves position of grip item on resize """ - if change == QGraphicsItem.ItemPositionChange and self.isEnabled(): p = QPointF(self.pos()) if self.direction == Qt.Horizontal: @@ -171,34 +152,34 @@ class SizeGripItem(GripItem): return super(SizeGripItem, self).itemChange(change, value) def removeFromCanvas(self): + # used to remove grip item from scene if self.scene(): self.scene().removeItem(self) class LineGripItem(GripItem): + """Extends grip items for connecting lines , with hover events and mouse events + """ circle = QPainterPath() circle.addEllipse(QRectF(-10, -10, 20, 20)) - def __init__(self, annotation_item, index, parent=None): - """ - Extends grip items for connecting lines , with hover events and mouse events - """ + + def __init__(self, annotation_item, index, location, parent=None): self.path = LineGripItem.circle - super(LineGripItem, self).__init__(annotation_item,path=self.path, parent=parent) + super(LineGripItem, self).__init__(annotation_item, path=self.path, parent=parent) self.m_index = index + self.m_location = location self.connectedLines = [] + # stores current line which is in process self.tempLine = None + # keep previous hovered item when line drawing in process self.previousHoveredItem = None self.setFlag(QGraphicsItem.ItemIsSelectable, True) - # self.setZValue(2) self.setPen(QPen(QColor("black"), -1)) - # self.setBrush(QColor("red")) - # self.setVisible(False) def point(self, index): """ yields a list of positions of grip items in a node item """ - radiusOfGripItem = self.boundingRect().width() / 2 x = self.m_annotation_item.boundingRect().width() y = self.m_annotation_item.boundingRect().height() if 0 <= index < 4: @@ -209,8 +190,7 @@ class LineGripItem(GripItem): QPointF(x, y / 2) ][index] - def update_position(self): - # print('updating grip item ', self.m_index) + def updatePosition(self): pos = self.point(self.m_index) x = self.m_annotation_item.boundingRect().x() y = self.m_annotation_item.boundingRect().y() @@ -223,133 +203,122 @@ class LineGripItem(GripItem): line.updateLine() def mousePressEvent(self, mouseEvent): + """Handle all mouse press for this item + """ if mouseEvent.button() != Qt.LeftButton: return - radiusOfGripItem = self.boundingRect().width() / 2 + # initialize a line and add on scene startPoint = endPoint = self.parentItem().mapToScene(self.pos()) - self.tempLine = Line(startPoint, endPoint) + self.tempLine.setStartGripItem(self) self.scene().addItem(self.tempLine) super().mousePressEvent(mouseEvent) def mouseMoveEvent(self, mouseEvent): + """Handle all mouse move for this item + """ + #if line get started then update it's end point if self.tempLine: endPoint = mouseEvent.scenePos() self.tempLine.updateLine(endPoint=endPoint) - super().mouseMoveEvent(mouseEvent) + item = self.scene().itemAt(mouseEvent.scenePos().x(), mouseEvent.scenePos().y(), self.m_annotation_item.transform()) - # print(self.m_annotation_item.transform()) if self.previousHoveredItem and item != self.previousHoveredItem and \ item not in self.previousHoveredItem.lineGripItems: self.previousHoveredItem.hideGripItem() + super().mouseMoveEvent(mouseEvent) if type(item) == NodeItem: self.previousHoveredItem = item item.showGripItem() def mouseReleaseEvent(self, mouseEvent): + """Handle all mouse release for this item""" + super().mouseReleaseEvent(mouseEvent) + # set final position of line if self.tempLine: item = self.scene().itemAt(mouseEvent.scenePos().x(), mouseEvent.scenePos().y(), self.transform()) - if type(item) == LineGripItem: + + if type(item) == LineGripItem and item != self: + self.tempLine.setEndGripItem(item) endPoint = item.parentItem().mapToScene(item.pos()) self.tempLine.updateLine(endPoint=endPoint) self.connectedLines.append(self.tempLine) item.connectedLines.append(self.tempLine) - self.tempLine.setStartGripItem(self) - self.tempLine.setEndGripItem(item) - else: + + + elif self.tempLine and self.scene(): self.scene().removeItem(self.tempLine) - super().mouseReleaseEvent(mouseEvent) self.tempLine = None self.previousHoveredItem = None def removeConnectedLines(self): + """removes all connected line to grip""" for line in self.connectedLines: line.removeFromCanvas() def show(self): + """ shows line grip item + """ self.setPen(QPen(QColor("black"), 2)) self.setBrush(QColor("red")) def hide(self): + """ hides line grip item + """ if (self.parentItem().isSelected() or self.isSelected()) is False: self.setPen(QPen(Qt.transparent)) self.setBrush(Qt.transparent) class NodeItem(QGraphicsSvgItem): + """ + Extends PyQt5's QGraphicsSvgItem to create the basic structure of shapes with given unit operation type + """ - def __init__(self, unitOpType, parent=None): + def __init__(self, unitOperationType, parent=None): QGraphicsSvgItem.__init__(self, parent) - self.m_renderer = QSvgRenderer() - self.type = unitOpType - - - self.file = QFile("svg/" + "Boiler" + ".svg") - if not self.file.open(QIODevice.ReadOnly): - print("Cannot open the file") - exit(-1) - self.svghandler = SvgHandler(self.file) - self.updateRenderer() - self.rect = QRectF(0,0,300,400) - # self.rect=QRectF(0,0,self.m_renderer.defaultSize().width(),self.m_renderer.defaultSize().height()) - # self.rect = self.m_renderer.viewBoxF() - # self.changeColour("red") - # self.changeStrokeWidth(4) - - self.setZValue(2) - self.setAcceptHoverEvents(True) - self.setAcceptDrops(True) + self.m_type = unitOperationType + self.m_renderer = QSvgRenderer("svg/" + unitOperationType + ".svg") + self.setSharedRenderer(self.m_renderer) + # set initial size of item + self.width = 100 + self.height = 150 + self.rect = QRectF(-self.width / 2, -self.height / 2, self.width, self.height) + # set graphical settings for this item self.setFlags(QGraphicsSvgItem.ItemIsMovable | QGraphicsSvgItem.ItemIsSelectable | QGraphicsSvgItem.ItemSendsGeometryChanges) - + self.setAcceptHoverEvents(True) + self.setZValue(2) + # grip items connected to this item self.lineGripItems = [] self.sizeGripItems = [] - self.ds= 0.70875001 - self.cs = 0.70875001 - self.dw=self.m_renderer.defaultSize().width() - self.dh=self.m_renderer.defaultSize().height() - self.vdw = self.m_renderer.viewBoxF().width() - self.vdh=self.m_renderer.viewBoxF().height() - - - def changeStrokeWidth(self,value): - self.svghandler.setStrokeWidth(value) - self.updateRenderer() - - def changeColour(self,value): - self.svghandler.setColor(value) - self.updateRenderer() - """graphics effect can also used to change colour of an svg image - """ - # self._effect = QGraphicsColorizeEffect() - # self._effect.setColor(Qt.red) - # self._effect.setStrength(1) - # self.setGraphicsEffect(self._effect) - - def updateRenderer(self): - byteArray = self.svghandler.doc.toByteArray() - self.m_renderer.load(byteArray) - self.setSharedRenderer(self.m_renderer) def boundingRect(self): + """Overrides QGraphicsSvgItem's boundingRect() virtual public function and + returns a valid bounding + """ return self.rect def paint(self, painter, option, widget): + """ + Paints the contents of an item in local coordinates. + :param painter: QPainter instance + :param option: QStyleOptionGraphicsItem instance + :param widget: QWidget instance + """ if not self.m_renderer: QGraphicsSvgItem.paint(self, painter, option, widget) self.m_renderer.render(painter, self.boundingRect()) - - def update_rect(self): - """Update rect of node item - """ - self.prepareGeometryChange() - self.update(self.rect) + if self.isSelected(): + self.showGripItem() + else: + self.hideGripItem() def resize(self, i, p): """Move grip item with changing rect of node item @@ -368,22 +337,26 @@ class NodeItem(QGraphicsSvgItem): if i == 2 or i == 3: self.rect = QRectF(x, y, width + p.x() - p_new.x(), height + p.y() - p_new.y()) - self.cs = self.ds*(self.boundingRect().width()/self.vdw) - # self.cs =self.s - print(self.boundingRect()) - print(self.cs) - offset = (self.cs-self.ds) - offset = offset*(self.vdw/self.boundingRect().width()) - # self.m_renderer.setViewBox(QRectF(offset/2.0,0,self.vdw-offset,self.vdh)) - - # self.update_rect() self.updateSizeGripItem([i]) self.updateLineGripItem() def addGripItem(self): """adds grip items """ - if self.scene() and not self.lineGripItems: + if self.scene(): + # add grip items for connecting lines + for i, (location) in enumerate( + ( + "top", + "left", + "bottom", + "right" + ) + ): + item = LineGripItem(self, i, location, parent=self) + self.scene().addItem(item) + self.lineGripItems.append(item) + # add grip for resize it for i, (direction) in enumerate( ( Qt.Vertical, @@ -392,29 +365,29 @@ class NodeItem(QGraphicsSvgItem): Qt.Horizontal, ) ): - item = LineGripItem(self, i) - item.setParentItem(self) - self.scene().addItem(item) - self.lineGripItems.append(item) item = SizeGripItem(self, i, direction) self.scene().addItem(item) self.sizeGripItems.append(item) def updateLineGripItem(self, index_no_updates=None): + """ + updates line grip items + """ # index_no_updates = index_no_updates or [] for item in self.lineGripItems: - item.update_position() + item.updatePosition() def updateSizeGripItem(self, index_no_updates=None): - """updates grip items + """ + updates size grip items """ index_no_updates = index_no_updates or [] for i, item in zip(range(len(self.sizeGripItems)), self.sizeGripItems): if i not in index_no_updates: - item.update_position() + item.updatePosition() def itemChange(self, change, value): - """Overloads and extends QGraphicsSvgItem to also update gripitem + """Overloads and extends QGraphicsSvgItem to also update grip items """ if change == QGraphicsItem.ItemPositionHasChanged: self.updateLineGripItem() @@ -427,12 +400,6 @@ class NodeItem(QGraphicsSvgItem): return return super(NodeItem, self).itemChange(change, value) - def addOnCanvas(self, scene): - """This function is used to add Node Item on canvas - :return: - """ - scene.addItem(self) - def removeFromCanvas(self): """This function is used to remove item from canvas :return: @@ -452,19 +419,21 @@ class NodeItem(QGraphicsSvgItem): def hoverLeaveEvent(self, event): """defines shape highlighting on Mouse Leave """ - # if self.isSelected() is False: self.hideGripItem() super(NodeItem, self).hoverLeaveEvent(event) def showGripItem(self): + """shows grip items of svg item + """ for item in self.lineGripItems: item.setPen(QPen(QColor("black"), 2)) item.setBrush(QColor("red")) for item in self.sizeGripItems: item.setPen(QPen(QColor("black"), 2)) - # item.setBrush(QColor("red")) def hideGripItem(self): + """hide grip items of svg item + """ for item in self.lineGripItems: if item.isSelected() is False: item.setPen(QPen(Qt.transparent)) @@ -472,4 +441,3 @@ class NodeItem(QGraphicsSvgItem): for item in self.sizeGripItems: item.setPen(QPen(Qt.transparent)) item.setBrush(Qt.transparent) - -- cgit From 4e62e7d565eb3932165c23bd1124817b0469b870 Mon Sep 17 00:00:00 2001 From: sumit Date: Tue, 19 May 2020 20:31:36 +0530 Subject: clean up' --- src/main/python/shapes/shapes.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/main/python/shapes/shapes.py') diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py index 982e882..034220e 100644 --- a/src/main/python/shapes/shapes.py +++ b/src/main/python/shapes/shapes.py @@ -320,24 +320,24 @@ class NodeItem(QGraphicsSvgItem): else: self.hideGripItem() - def resize(self, i, p): + def resize(self, index, p): """Move grip item with changing rect of node item """ x = self.boundingRect().x() y = self.boundingRect().y() width = self.boundingRect().width() height = self.boundingRect().height() - p_new = self.sizeGripItems[i].pos() + pos_new = self.sizeGripItems[index].pos() self.prepareGeometryChange() - if i == 0 or i == 1: - self.rect = QRectF(x + p.x() - p_new.x(), y + p.y() - p_new.y(), width - p.x() + p_new.x(), - height - p.y() + p_new.y()) + if index == 0 or index == 1: + self.rect = QRectF(x + p.x() - pos_new.x(), y + p.y() - pos_new.y(), width - p.x() + pos_new.x(), + height - p.y() + pos_new.y()) - if i == 2 or i == 3: - self.rect = QRectF(x, y, width + p.x() - p_new.x(), height + p.y() - p_new.y()) + if index == 2 or index == 3: + self.rect = QRectF(x, y, width + p.x() - pos_new.x(), height + p.y() - pos_new.y()) - self.updateSizeGripItem([i]) + self.updateSizeGripItem([index]) self.updateLineGripItem() def addGripItem(self): -- cgit From cac1ceb55b5369fa2d5bef4f96092e594cf87881 Mon Sep 17 00:00:00 2001 From: sumit Date: Wed, 20 May 2020 07:42:26 +0530 Subject: cleanup --- src/main/python/shapes/shapes.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/main/python/shapes/shapes.py') diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py index 034220e..c0ddb0f 100644 --- a/src/main/python/shapes/shapes.py +++ b/src/main/python/shapes/shapes.py @@ -320,22 +320,22 @@ class NodeItem(QGraphicsSvgItem): else: self.hideGripItem() - def resize(self, index, p): + def resize(self, index, new_pos): """Move grip item with changing rect of node item """ x = self.boundingRect().x() y = self.boundingRect().y() width = self.boundingRect().width() height = self.boundingRect().height() - pos_new = self.sizeGripItems[index].pos() + old_pos = self.sizeGripItems[index].pos() self.prepareGeometryChange() if index == 0 or index == 1: - self.rect = QRectF(x + p.x() - pos_new.x(), y + p.y() - pos_new.y(), width - p.x() + pos_new.x(), - height - p.y() + pos_new.y()) + self.rect = QRectF(x + new_pos.x() - old_pos.x(), y + new_pos.y() - old_pos.y(), width - new_pos.x() + old_pos.x(), + height - new_pos.y() + old_pos.y()) if index == 2 or index == 3: - self.rect = QRectF(x, y, width + p.x() - pos_new.x(), height + p.y() - pos_new.y()) + self.rect = QRectF(x, y, width + new_pos.x() - old_pos.x(), height + new_pos.y() - old_pos.y()) self.updateSizeGripItem([index]) self.updateLineGripItem() -- cgit From 10f48f628b15d9cca192f17a377abcbdd8e6716f Mon Sep 17 00:00:00 2001 From: sumit Date: Thu, 21 May 2020 08:27:36 +0530 Subject: add class for pfd-symbols --- src/main/python/shapes/shapes.py | 295 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 291 insertions(+), 4 deletions(-) (limited to 'src/main/python/shapes/shapes.py') diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py index c0ddb0f..884659c 100644 --- a/src/main/python/shapes/shapes.py +++ b/src/main/python/shapes/shapes.py @@ -1,3 +1,4 @@ +# from fbs_runtime.application_context.PyQt5 import ApplicationContext from PyQt5 import QtCore, QtWidgets from PyQt5.QtSvg import QGraphicsSvgItem, QSvgRenderer from PyQt5.QtWidgets import QLineEdit, QGraphicsItem, QGraphicsEllipseItem, QGraphicsProxyWidget, QGraphicsPathItem, \ @@ -5,7 +6,10 @@ from PyQt5.QtWidgets import QLineEdit, QGraphicsItem, QGraphicsEllipseItem, QGra from PyQt5.QtGui import QPen, QColor, QFont, QCursor, QPainterPath, QPainter, QDrag, QBrush, QImage from PyQt5.QtCore import Qt, QRectF, QPointF, QSizeF, QEvent, QMimeData, QFile, QIODevice, QRect -from line import Line +from .line import Line + + +# resourceManager = ApplicationContext() class GripItem(QGraphicsPathItem): @@ -48,6 +52,7 @@ class GripItem(QGraphicsPathItem): self.setSelected(False) super(GripItem, self).mouseReleaseEvent(event) + class SizeGripItem(GripItem): """ Extends grip items for vertical and horizontal directions, with hover events and directional changes @@ -217,7 +222,7 @@ class LineGripItem(GripItem): def mouseMoveEvent(self, mouseEvent): """Handle all mouse move for this item """ - #if line get started then update it's end point + # if line get started then update it's end point if self.tempLine: endPoint = mouseEvent.scenePos() self.tempLine.updateLine(endPoint=endPoint) @@ -284,6 +289,7 @@ class NodeItem(QGraphicsSvgItem): QGraphicsSvgItem.__init__(self, parent) self.m_type = unitOperationType self.m_renderer = QSvgRenderer("svg/" + unitOperationType + ".svg") + # self.m_renderer = QSvgRenderer(resourceManager.get_resource(f'toolbar/{unitOperationType}.svg')) self.setSharedRenderer(self.m_renderer) # set initial size of item self.width = 100 @@ -331,7 +337,8 @@ class NodeItem(QGraphicsSvgItem): self.prepareGeometryChange() if index == 0 or index == 1: - self.rect = QRectF(x + new_pos.x() - old_pos.x(), y + new_pos.y() - old_pos.y(), width - new_pos.x() + old_pos.x(), + self.rect = QRectF(x + new_pos.x() - old_pos.x(), y + new_pos.y() - old_pos.y(), + width - new_pos.x() + old_pos.x(), height - new_pos.y() + old_pos.y()) if index == 2 or index == 3: @@ -354,7 +361,7 @@ class NodeItem(QGraphicsSvgItem): ) ): item = LineGripItem(self, i, location, parent=self) - self.scene().addItem(item) + # self.scene().addItem(item) self.lineGripItems.append(item) # add grip for resize it for i, (direction) in enumerate( @@ -441,3 +448,283 @@ class NodeItem(QGraphicsSvgItem): for item in self.sizeGripItems: item.setPen(QPen(Qt.transparent)) item.setBrush(Qt.transparent) + +#classes of pfd-symbols +class AirBlownCooler(NodeItem): + def __init__(self): + super(AirBlownCooler, self).__init__("AirBlownCooler", parent=None) + + +class Bag(NodeItem): + def __init__(self): + super(Bag, self).__init__("Bag", parent=None) + + +class Boiler(NodeItem): + def __init__(self): + super(Boiler, self).__init__("Boiler", parent=None) + + +class Breaker(NodeItem): + def __init__(self): + super(Breaker, self).__init__("Breaker", parent=None) + + +class BriquettingMachine(NodeItem): + def __init__(self): + super(BriquettingMachine, self).__init__("BriquettingMachine", parent=None) + + +class Centrifugal(NodeItem): + def __init__(self): + super(Centrifugal, self).__init__("Centrifugal", parent=None) + + +class CentrifugalCompressor(NodeItem): + def __init__(self): + super(CentrifugalCompressor, self).__init__("CentrifugalCompressor", parent=None) + + +class Centrifugalpump(NodeItem): + def __init__(self): + super(Centrifugalpump, self).__init__("Centrifugalpump", parent=None) + + +class CentrifugalPump2(NodeItem): + def __init__(self): + super(CentrifugalPump2, self).__init__("CentrifugalPump2", parent=None) + + +class CentrifugalPump3(NodeItem): + def __init__(self): + super(CentrifugalPump3, self).__init__("CentrifugalPump3", parent=None) + + +class Column(NodeItem): + def __init__(self): + super(Column, self).__init__("Column", parent=None) + + +class Compressor(NodeItem): + def __init__(self): + super(Compressor, self).__init__("Compressor", parent=None) + + +class CompressorSilencers(NodeItem): + def __init__(self): + super(CompressorSilencers, self).__init__("CompressorSilencers", parent=None) + + +class Condenser(NodeItem): + def __init__(self): + super(Condenser, self).__init__("Condenser", parent=None) + + +class Cooler(NodeItem): + def __init__(self): + super(Cooler, self).__init__("Cooler", parent=None) + + +class CoolingTower3(NodeItem): + def __init__(self): + super(CoolingTower3, self).__init__("CoolingTower3", parent=None) + + +class CoolingTwoer2(NodeItem): + def __init__(self): + super(CoolingTwoer2, self).__init__("CoolingTwoer2", parent=None) + + +class Crusher(NodeItem): + def __init__(self): + super(Crusher, self).__init__("Crusher", parent=None) + + +class DoublePipeHeat(NodeItem): + def __init__(self): + super(DoublePipeHeat, self).__init__("DoublePipeHeat", parent=None) + + +class ExtractorHood(NodeItem): + def __init__(self): + super(ExtractorHood, self).__init__("ExtractorHood", parent=None) + + +class FiredHeater(NodeItem): + def __init__(self): + super(FiredHeater, self).__init__("FiredHeater", parent=None) + + +class ForcedDraftCooling(NodeItem): + def __init__(self): + super(ForcedDraftCooling, self).__init__("ForcedDraftCooling", parent=None) + + +class Furnace(NodeItem): + def __init__(self): + super(Furnace, self).__init__("Furnace", parent=None) + + +class GasBottle(NodeItem): + def __init__(self): + super(GasBottle, self).__init__("GasBottle", parent=None) + + +class HalfPipeMixingVessel(NodeItem): + def __init__(self): + super(HalfPipeMixingVessel, self).__init__("HalfPipeMixingVessel", parent=None) + + +class Heater(NodeItem): + def __init__(self): + super(Heater, self).__init__("Heater", parent=None) + + +class HeatExchanger(NodeItem): + def __init__(self): + super(HeatExchanger, self).__init__("HeatExchanger", parent=None) + + +class HeatExchanger2(NodeItem): + def __init__(self): + super(HeatExchanger2, self).__init__("HeatExchanger2", parent=None) + + +class HorizontalVessel(NodeItem): + def __init__(self): + super(HorizontalVessel, self).__init__("HorizontalVessel", parent=None) + + +class InducedDraftCooling(NodeItem): + def __init__(self): + super(InducedDraftCooling, self).__init__("InducedDraftCooling", parent=None) + + +class jacketedMixingVessel(NodeItem): + def __init__(self): + super(jacketedMixingVessel, self).__init__("jacketedMixingVessel", parent=None) + + +class LiquidRingCompressor(NodeItem): + def __init__(self): + super(LiquidRingCompressor, self).__init__("LiquidRingCompressor", parent=None) + + +class Mixing(NodeItem): + def __init__(self): + super(Mixing, self).__init__("Mixing", parent=None) + + +class MixingReactor(NodeItem): + def __init__(self): + super(MixingReactor, self).__init__("MixingReactor", parent=None) + + +class OilBurner(NodeItem): + def __init__(self): + super(OilBurner, self).__init__("OilBurner", parent=None) + + +class OpenTank(NodeItem): + def __init__(self): + super(OpenTank, self).__init__("OpenTank", parent=None) + + +class ProportionalPump(NodeItem): + def __init__(self): + super(ProportionalPump, self).__init__("ProportionalPump", parent=None) + + +class Pump(NodeItem): + def __init__(self): + super(Pump, self).__init__("Pump", parent=None) + + +class Pump2(NodeItem): + def __init__(self): + super(Pump2, self).__init__("Pump2", parent=None) + + +class ReboilerHeatExchange(NodeItem): + def __init__(self): + super(ReboilerHeatExchange, self).__init__("ReboilerHeatExchange", parent=None) + + +class ReciprocatingCompressor(NodeItem): + def __init__(self): + super(ReciprocatingCompressor, self).__init__("ReciprocatingCompressor", parent=None) + + +class RotaryCompresor(NodeItem): + def __init__(self): + super(RotaryCompresor, self).__init__("RotaryCompresor", parent=None) + + +class RotaryGearPump(NodeItem): + def __init__(self): + super(RotaryGearPump, self).__init__("RotaryGearPump", parent=None) + + +class ScrewPump(NodeItem): + def __init__(self): + super(ScrewPump, self).__init__("ScrewPump", parent=None) + + +class SelectableCompressor(NodeItem): + def __init__(self): + super(SelectableCompressor, self).__init__("SelectableCompressor", parent=None) + + +class SelectableFan(NodeItem): + def __init__(self): + super(SelectableFan, self).__init__("SelectableFan", parent=None) + + +class SinglePassHeat(NodeItem): + def __init__(self): + super(SinglePassHeat, self).__init__("SinglePassHeat", parent=None) + + +class SpiralHeatExchanger(NodeItem): + def __init__(self): + super(SpiralHeatExchanger, self).__init__("SpiralHeatExchanger", parent=None) + + +class StraightTubersHeat(NodeItem): + def __init__(self): + super(StraightTubersHeat, self).__init__("StraightTubersHeat", parent=None) + + +class Tank(NodeItem): + def __init__(self): + super(Tank, self).__init__("Tank", parent=None) + + +class TurbinePump(NodeItem): + def __init__(self): + super(TurbinePump, self).__init__("TurbinePump", parent=None) + + +class UTubeHeatExchanger(NodeItem): + def __init__(self): + super(UTubeHeatExchanger, self).__init__("UTubeHeatExchanger", parent=None) + + +class VaccumPump(NodeItem): + def __init__(self): + super(VaccumPump, self).__init__("VaccumPump", parent=None) + + +class VerticalPump(NodeItem): + def __init__(self): + super(VerticalPump, self).__init__("VerticalPump", parent=None) + + +class VerticalVessel(NodeItem): + def __init__(self): + super(VerticalVessel, self).__init__("VerticalVessel", parent=None) + + +class WastewaterTreatment(NodeItem): + def __init__(self): + super(WastewaterTreatment, self).__init__("WastewaterTreatment", parent=None) -- cgit From e1d6fd3e9eb9daccb7f3ef0d26ab60a2aec25178 Mon Sep 17 00:00:00 2001 From: sumit Date: Thu, 21 May 2020 15:01:14 +0530 Subject: svg origin at center and size grip as child --- src/main/python/shapes/shapes.py | 120 +++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 54 deletions(-) (limited to 'src/main/python/shapes/shapes.py') diff --git a/src/main/python/shapes/shapes.py b/src/main/python/shapes/shapes.py index 884659c..210d68e 100644 --- a/src/main/python/shapes/shapes.py +++ b/src/main/python/shapes/shapes.py @@ -3,10 +3,10 @@ from PyQt5 import QtCore, QtWidgets from PyQt5.QtSvg import QGraphicsSvgItem, QSvgRenderer from PyQt5.QtWidgets import QLineEdit, QGraphicsItem, QGraphicsEllipseItem, QGraphicsProxyWidget, QGraphicsPathItem, \ QGraphicsSceneHoverEvent, QGraphicsColorizeEffect -from PyQt5.QtGui import QPen, QColor, QFont, QCursor, QPainterPath, QPainter, QDrag, QBrush, QImage +from PyQt5.QtGui import QPen, QColor, QFont, QCursor, QPainterPath, QPainter, QDrag, QBrush, QImage, QTransform from PyQt5.QtCore import Qt, QRectF, QPointF, QSizeF, QEvent, QMimeData, QFile, QIODevice, QRect -from .line import Line +from line import Line # resourceManager = ApplicationContext() @@ -66,7 +66,7 @@ class SizeGripItem(GripItem): self.width = annotation_item.boundingRect().width() path = QPainterPath() - path.addRect(QRectF(0, 0, self.width, self.height)) + path.addRect(QRectF(-self.width/2, -self.height/2, self.width, self.height)) super(SizeGripItem, self).__init__(annotation_item, path=path, parent=parent) self.setFlag(QGraphicsItem.ItemIsSelectable, True) self.setFlag(QGraphicsItem.ItemIsMovable, True) @@ -83,26 +83,28 @@ class SizeGripItem(GripItem): """ return self._direction + def paint(self, painter, option, widget): + if self.isSelected() and not self.parentItem().isSelected(): + self.parentItem().setSelected(True) + self.parentItem().setFlag(QGraphicsSvgItem.ItemIsMovable, False) + super().paint(painter, option, widget) + def updatePath(self): """updates path of size grip item """ if self._direction is Qt.Horizontal: - self.height = self.m_annotation_item.boundingRect().height() + self.height = self.parentItem().boundingRect().height() else: - self.width = self.m_annotation_item.boundingRect().width() + self.width = self.parentItem().boundingRect().width() path = QPainterPath() - path.addRect(QRectF(0, 0, self.width, self.height)) + path.addRect(QRectF(-self.width/2, -self.height/2, self.width, self.height)) self.setPath(path) def updatePosition(self): """updates position of grip items """ self.updatePath() - pos = self.m_annotation_item.mapToScene(self.point(self.m_index)) - x = self.m_annotation_item.boundingRect().x() - y = self.m_annotation_item.boundingRect().y() - pos.setX(pos.x() + x) - pos.setY(pos.y() + y) + pos = self.point(self.m_index) self.setEnabled(False) self.setPos(pos) self.setEnabled(True) @@ -111,14 +113,14 @@ class SizeGripItem(GripItem): """ yields a list of positions of grip items in a node item """ - x = self.m_annotation_item.boundingRect().width() - y = self.m_annotation_item.boundingRect().height() + width = self.parentItem().boundingRect().width() + height = self.parentItem().boundingRect().height() if 0 <= index < 4: return [ - QPointF(0, 0), - QPointF(0, 0), - QPointF(0, y), - QPointF(x, 0) + QPointF(0, -height / 2), + QPointF(-width / 2, 0), + QPointF(0, height / 2), + QPointF(width / 2, 0) ][index] def hoverEnterEvent(self, event): @@ -152,14 +154,26 @@ class SizeGripItem(GripItem): p.setX(value.x()) elif self.direction == Qt.Vertical: p.setY(value.y()) - self.m_annotation_item.resize(self.m_index, p) + # Find change in positions + movement = p - self.pos() + # Set transform to oppose change in transformation due to parent + transform = QTransform() + transform.translate(-movement.x() / 2, -movement.y() / 2) + self.setTransform(transform, True) + self.parentItem().resize(self.m_index, movement) return p return super(SizeGripItem, self).itemChange(change, value) - def removeFromCanvas(self): - # used to remove grip item from scene - if self.scene(): - self.scene().removeItem(self) + def mouseReleaseEvent(self, event): + super(SizeGripItem, self).mouseReleaseEvent(event) + # Reset transform and update position + self.resetTransform() + self.updatePosition() + # Make parent item move able + self.parentItem().setFlag(QGraphicsSvgItem.ItemIsMovable, True) + # If needed to reset transform of parent set it's position accordingly + # self.parentItem().setPos(self.parentItem().x() + self.parentItem().transform().dx(), self.parentItem().y() + self.parentItem().transform().dy()) + # self.parentItem().resetTransform() class LineGripItem(GripItem): @@ -185,22 +199,18 @@ class LineGripItem(GripItem): """ yields a list of positions of grip items in a node item """ - x = self.m_annotation_item.boundingRect().width() - y = self.m_annotation_item.boundingRect().height() + width = self.parentItem().boundingRect().width() + height = self.parentItem().boundingRect().height() if 0 <= index < 4: return [ - QPointF(x / 2, 0), - QPointF(0, y / 2), - QPointF(x / 2, y), - QPointF(x, y / 2) + QPointF(0, -height / 2), + QPointF(-width / 2, 0), + QPointF(0, height / 2), + QPointF(width / 2, 0) ][index] def updatePosition(self): pos = self.point(self.m_index) - x = self.m_annotation_item.boundingRect().x() - y = self.m_annotation_item.boundingRect().y() - pos.setX(pos.x() + x) - pos.setY(pos.y() + y) self.setEnabled(False) self.setPos(pos) self.setEnabled(True) @@ -228,7 +238,7 @@ class LineGripItem(GripItem): self.tempLine.updateLine(endPoint=endPoint) item = self.scene().itemAt(mouseEvent.scenePos().x(), mouseEvent.scenePos().y(), - self.m_annotation_item.transform()) + self.parentItem().transform()) if self.previousHoveredItem and item != self.previousHoveredItem and \ item not in self.previousHoveredItem.lineGripItems: @@ -323,29 +333,23 @@ class NodeItem(QGraphicsSvgItem): self.m_renderer.render(painter, self.boundingRect()) if self.isSelected(): self.showGripItem() - else: - self.hideGripItem() - def resize(self, index, new_pos): + def resize(self, index, movement): """Move grip item with changing rect of node item """ - x = self.boundingRect().x() - y = self.boundingRect().y() - width = self.boundingRect().width() - height = self.boundingRect().height() - old_pos = self.sizeGripItems[index].pos() self.prepareGeometryChange() + if index in [0, 1]: + self.width -= movement.x() + self.height -= movement.y() + else: + self.width += movement.x() + self.height += movement.y() - if index == 0 or index == 1: - self.rect = QRectF(x + new_pos.x() - old_pos.x(), y + new_pos.y() - old_pos.y(), - width - new_pos.x() + old_pos.x(), - height - new_pos.y() + old_pos.y()) - - if index == 2 or index == 3: - self.rect = QRectF(x, y, width + new_pos.x() - old_pos.x(), height + new_pos.y() - old_pos.y()) - + self.rect = QRectF(-self.width / 2, -self.height / 2, self.width, self.height) + transform = QTransform() + transform.translate(movement.x() / 2, movement.y() / 2) + self.setTransform(transform, True) self.updateSizeGripItem([index]) - self.updateLineGripItem() def addGripItem(self): """adds grip items @@ -361,7 +365,6 @@ class NodeItem(QGraphicsSvgItem): ) ): item = LineGripItem(self, i, location, parent=self) - # self.scene().addItem(item) self.lineGripItems.append(item) # add grip for resize it for i, (direction) in enumerate( @@ -372,8 +375,7 @@ class NodeItem(QGraphicsSvgItem): Qt.Horizontal, ) ): - item = SizeGripItem(self, i, direction) - self.scene().addItem(item) + item = SizeGripItem(self, i, direction, parent=self) self.sizeGripItems.append(item) def updateLineGripItem(self, index_no_updates=None): @@ -396,6 +398,15 @@ class NodeItem(QGraphicsSvgItem): def itemChange(self, change, value): """Overloads and extends QGraphicsSvgItem to also update grip items """ + if change == QGraphicsItem.ItemSelectedHasChanged: + if value is True: + self.showGripItem() + else: + self.hideGripItem() + return + if change == QGraphicsItem.ItemTransformHasChanged: + self.updateLineGripItem() + return if change == QGraphicsItem.ItemPositionHasChanged: self.updateLineGripItem() self.updateSizeGripItem() @@ -449,7 +460,8 @@ class NodeItem(QGraphicsSvgItem): item.setPen(QPen(Qt.transparent)) item.setBrush(Qt.transparent) -#classes of pfd-symbols + +# classes of pfd-symbols class AirBlownCooler(NodeItem): def __init__(self): super(AirBlownCooler, self).__init__("AirBlownCooler", parent=None) -- cgit