diff options
author | lucaszhao19 | 2019-12-23 13:25:49 +0530 |
---|---|---|
committer | lucaszhao19 | 2019-12-23 13:25:49 +0530 |
commit | 9f86138b86efebb816a2289bf84b96d688615f41 (patch) | |
tree | c3213fb23a240130186adab4f1c523443d83c319 /Graphics.py | |
parent | e2113828e404349f15b98d6c29e119a11abdab01 (diff) | |
download | Chemical-Simulator-GUI-9f86138b86efebb816a2289bf84b96d688615f41.tar.gz Chemical-Simulator-GUI-9f86138b86efebb816a2289bf84b96d688615f41.tar.bz2 Chemical-Simulator-GUI-9f86138b86efebb816a2289bf84b96d688615f41.zip |
Feature implementation - saving and partial loading
Diffstat (limited to 'Graphics.py')
-rw-r--r-- | Graphics.py | 374 |
1 files changed, 374 insertions, 0 deletions
diff --git a/Graphics.py b/Graphics.py new file mode 100644 index 0000000..4d0a5ea --- /dev/null +++ b/Graphics.py @@ -0,0 +1,374 @@ +from functools import partial +from collections import defaultdict +import sys +import numpy as np +from OMChem.Flowsheet import Flowsheet +from OMChem.MatStm import MatStm +from OMChem.Mixer import Mixer +from OMChem.Heater import Heater +from OMChem.Splitter import Splitter +from OMChem.ShortcutColumn import ShortcutColumn + +import pandas as pd +from PyQt5.QtCore import * +from PyQt5.QtWidgets import * +from PyQt5.QtGui import QTextDocument ,QTextCursor ,QTextCharFormat ,QFont ,QPixmap +from PyQt5.uic import loadUiType +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QGraphicsProxyWidget, QGraphicsObject, QGraphicsEllipseItem ,QGraphicsPixmapItem,QApplication, QGraphicsView, QGraphicsScene, QHBoxLayout, QWidget, QLabel +from PyQt5.QtGui import QBrush ,QTransform ,QMouseEvent +import PyQt5.QtGui as QtGui +import PyQt5.QtCore as QtCore +import PyQt5.QtWidgets as QtWidgets +from component_selector import * +from dockWidget import dockWidget +from resDockWidget import resdockWidget +from helper import helperFunc +import datetime +from container import Container + +class Graphics(QDialog): + + def __init__(self): + QDialog.__init__(self) + self.scene = QGraphicsScene() + self.scene.setItemIndexMethod(QGraphicsScene.BspTreeIndex) + + def getScene(self): + return self.scene + + '''def getContainer(self, textBrowser): + return Container(textBrowser) + + def getComponentSelector(self): + return componentSelector(self)''' + + def createNodeItem(self, conntype, container): + return NodeItem(conntype, container) + +class NodeLine(QtWidgets.QGraphicsPathItem): + def __init__(self, pointA, pointB , socket): + super(NodeLine, self).__init__() + self._pointA = pointA + self._pointB = pointB + self.socket = socket + self._source = None + self._target = None + self.setZValue(-1) + self.setBrush(QtGui.QColor(0,0,255,255)) + self.pen = QtGui.QPen() + + self.pen.setStyle(QtCore.Qt.SolidLine) + self.pen.setWidth(1) + self.pen.setColor(QtGui.QColor(0,0,255,255)) + self.setPen(self.pen) + + def updatePath(self): + path = QtGui.QPainterPath() + path.moveTo(self.pointA) + midptx = 0.5*(self.pointA.x() + self.pointB.x()) + + + ctrl1_1 = QtCore.QPointF(self.pointA.x(), self.pointA.y()) + ctrl2_1 = QtCore.QPointF(self.pointA.x(), self.pointA.y()) + pt1 = QtCore.QPointF(midptx , self.pointA.y()) + path.cubicTo(ctrl1_1, ctrl2_1, pt1) + + path.moveTo(pt1) + + ctrl1_2 = QtCore.QPointF(midptx, self.pointB.y()) + ctrl2_2 = QtCore.QPointF(midptx, self.pointB.y()) + pt2 = QtCore.QPointF(midptx , self.pointB.y()) + path.cubicTo(ctrl1_2, ctrl2_2, pt2) + path.moveTo(pt2) + + ctrl1_3 = QtCore.QPointF(midptx, self.pointB.y()) + ctrl2_3 = QtCore.QPointF(midptx, self.pointB.y()) + path.cubicTo(ctrl1_3, ctrl2_3, self.pointB) + self.setPath(path) + + def paint(self, painter, option, widget): + painter.setPen(self.pen) + painter.drawPath(self.path()) + + @property + def pointA(self): + #print('a') + return self._pointA + + @pointA.setter + def pointA(self, point): + #print('seta') + self._pointA = point + self.updatePath() + + @property + def pointB(self): + #print('b') + return self._pointB + + @pointB.setter + def pointB(self, point): + #print('set b') + self._pointB = point + self.updatePath() + + @property + def source(self): + #print('source') + return self._source + + @source.setter + def source(self, widget): + #print('set source') + self._source = widget + + @property + def target(self): + #print('target') + return self._target + + @target.setter + def target(self, widget): + #print('set target') + self._target = widget + + def __delete__(self,instance): + del self._source + del self._target + del self._pointA + del self._pointB + +class NodeSocket(QtWidgets.QGraphicsItem): + def __init__(self, rect, parent, socketType,container): + super(NodeSocket, self).__init__(parent) + self.rect = rect + self.type = socketType + self.parent=parent + self.container=container + self.newLine=None + self.otherLine=None + + # Brush. + self.brush = QtGui.QBrush() + self.brush.setStyle(QtCore.Qt.SolidPattern) + self.brush.setColor(QtGui.QColor(180,20,90,255)) + # Pen. + self.pen = QtGui.QPen() + self.pen.setStyle(QtCore.Qt.SolidLine) + self.pen.setWidth(1) + self.pen.setColor(QtGui.QColor(20,20,20,255)) + + # Lines. + self.outLines = [] + self.inLines = [] + + def shape(self): + path = QtGui.QPainterPath() + path.addEllipse(self.boundingRect()) + return path + + def boundingRect(self): + return QtCore.QRectF(self.rect) + + def paint(self, painter, option, widget): + painter.setBrush(self.brush) + painter.setPen(self.pen) + painter.drawEllipse(self.rect) + + def mousePressEvent(self, event): + if self.type == 'op': + rect = self.boundingRect() + pointA = QtCore.QPointF(rect.x() + rect.width()/2, rect.y() + rect.height()/2) + pointA = self.mapToScene(pointA) + pointB = self.mapToScene(event.pos()) + self.newLine = NodeLine(pointA, pointB ,'op') + self.outLines.append(self.newLine) + self.scene().addItem(self.newLine) + elif self.type == 'in': + rect = self.boundingRect() + pointA = self.mapToScene(event.pos()) + pointB = QtCore.QPointF(rect.x() + rect.width()/2, rect.y() + rect.height()/2) + pointB = self.mapToScene(pointB) + self.newLine = NodeLine(pointA, pointB, 'in') + self.inLines.append(self.newLine) + self.scene().addItem(self.newLine) + else: + super(NodeSocket, self).mousePressEvent(event) + + def mouseMoveEvent(self, event): + if self.type == 'op': + pointB = self.mapToScene(event.pos()) + self.newLine.pointB = pointB + if self.otherLine: + self.otherLine.pointB=pointB + + elif self.type == 'in': + pointA = self.mapToScene(event.pos()) + self.newLine.pointA = pointA + if self.otherLine: + self.otherLine.pointA=pointA + else: + super(NodeSocket, self).mouseMoveEvent(event) + + def mouseReleaseEvent(self, event): + item = self.scene().itemAt(event.scenePos().toPoint(),QtGui.QTransform()) + item.otherLine=self.newLine + if (self.type == 'op') and (item.type == 'in'): + self.newLine.source = self + self.newLine.target = item + item.inLines.append(self.newLine) + self.newLine.pointB = item.getCenter() + self.container.updateConn(self.newLine.source.parent.obj,self.newLine.target.parent.obj) + elif (self.type =='in') and (item.type == 'op'): + self.newLine.source = item + self.newLine.target = self + item.outLines.append(self.newLine) + self.newLine.pointA = item.getCenter() + self.container.updateConn(self.newLine.source.parent.obj,self.newLine.target.parent.obj) + else: + self.scene().removeItem(self.newLine) + if(self.newLine in self.inLines): + self.inLines.remove(self.newLine) + if(self.newLine in self.outLines): + self.outLines.remove(self.newLine) + del self.newLine + super(NodeSocket, self).mouseReleaseEvent(event) + + def getCenter(self): + rect = self.boundingRect() + center = QtCore.QPointF(rect.x() + rect.width()/2, rect.y() + rect.height()/2) + center = self.mapToScene(center) + return center + +class NodeItem(QtWidgets.QGraphicsItem): + def __init__(self,comptype,container): + l = ['Mixer','Splitter'] + super(NodeItem, self).__init__() + self.type = comptype + + # for creating unit operation objects without helper function + if (self.type == 'MatStm'): + self.obj = MatStm(CompNames=compound_selected) + elif (self.type == 'ShortCol'): # the only class that class name and type does not match + self.obj = ShortcutColumn() + else: + self.obj = eval(self.type)() + + + #self.obj = myhelperFunc(self.type) + self.name = self.obj.getname() + self.pos = None + self.setToolTip(self.name) + self.nin = self.obj.no_of_input + self.nop = self.obj.no_of_output + + self.container=container + self.container.addUnitOp(self.obj) + if(self.type not in l): + self.mainwindow= findMainWindow(self) + self.dockWidget=dockWidget(self.name,self.type,self.obj) + self.mainwindow.addDockWidget(Qt.LeftDockWidgetArea, self.dockWidget) + self.dockWidget.hide() + + self.pic=QtGui.QPixmap("icons/"+self.type+".png") + self.rect = QtCore.QRect(0,0,self.pic.width(),self.pic.height()) + self.text = QGraphicsTextItem(self) + f = QFont() + f.setPointSize(8) + self.text.setFont(f) + self.text.setDefaultTextColor(QtGui.QColor(73,36,73,255)) + self.text.setParentItem(self) + self.text.setPos(-2.5, self.rect.height()-15) + self.text.setPlainText(self.name) + + self.setFlag(QtWidgets.QGraphicsPixmapItem.ItemIsMovable) + self.setFlag(QtWidgets.QGraphicsPixmapItem.ItemIsSelectable) + self.initUi() + + # Brush + self.brush = QtGui.QBrush() + self.brush.setStyle(QtCore.Qt.SolidPattern) + self.brush.setColor(QtGui.QColor(80,0,90,255)) + # Pen. + self.pen = QtGui.QPen() + self.pen.setStyle(QtCore.Qt.SolidLine) + self.pen.setWidth(1) + self.pen.setColor(QtGui.QColor(20,20,20,255)) + + self.selPen = QtGui.QPen() + self.selPen.setStyle(QtCore.Qt.SolidLine) + self.selPen.setWidth(2) + self.selPen.setColor(QtGui.QColor(222,192,222)) + + def initUi(self): + self.Input , self.Output = self.initializeSockets(self.type) + + def shape(self): + path = QtGui.QPainterPath() + path.addRect(self.boundingRect()) + return path + + def boundingRect(self): + return QtCore.QRectF(self.rect) + + def paint(self, painter, option, widget): + if self.isSelected(): + painter.setPen(self.selPen) + painter.drawRect(QtCore.QRectF(self.rect)) + else: + painter.setPen(self.pen) + painter.drawPixmap(self.rect,self.pic) + + def initializeSockets(self,type): + if(self.type=="Flash" or self.type=="CompSep"): + Input = [NodeSocket(QtCore.QRect(-2.5+5.5,(self.rect.height()*x/(self.nin+1))-8,4,4), self, 'in',self.container) for x in range(1,self.nin+1) ] + Output = [NodeSocket(QtCore.QRect(self.rect.width()-7.5,(self.rect.height()*x*0.90/(self.nop+1))-4,4,4), self, 'op',self.container) for x in range(1,self.nop+1)] + return Input,Output + elif(self.type=="AdiaComp" or self.type=="AdiaExp" or self.type =="Mixer" or self.type =="Splitter" or self.type =="Valve" ): + Input = [NodeSocket(QtCore.QRect(-3.5,(self.rect.height()*x/(self.nin+1))-6,4,4), self, 'in',self.container) for x in range(1,self.nin+1) ] + Output = [NodeSocket(QtCore.QRect(self.rect.width()-2.5,(self.rect.height()*x/(self.nop+1))-6,4,4), self, 'op',self.container) for x in range(1,self.nop+1)] + return Input,Output + elif(self.type=="Cooler" or self.type=="Heater"): + Input = [NodeSocket(QtCore.QRect(3.5,(self.rect.height()*x/(self.nin+1))-4,4,4), self, 'in',self.container) for x in range(1,self.nin+1) ] + Output = [NodeSocket(QtCore.QRect(self.rect.width()-8.0,(self.rect.height()*x/(self.nop+1))-4,4,4), self, 'op',self.container) for x in range(1,self.nop+1)] + return Input,Output + elif(self.type=="Pump"): + Input = [NodeSocket(QtCore.QRect(-2.5,(self.rect.height()*x/(self.nin+1))-10,4,4), self, 'in',self.container) for x in range(1,self.nin+1) ] + Output = [NodeSocket(QtCore.QRect(self.rect.width()-2.5,-2.5,4,4), self, 'op',self.container) for x in range(1,self.nop+1)] + return Input,Output + elif(self.type=="DistCol" or self.type=="ShortCol"): + Input = [NodeSocket(QtCore.QRect(-2.5,(self.rect.height()*x/(self.nin+1))-12,5,5), self, 'in',self.container) for x in range(1,self.nin+1) ] + Output = [NodeSocket(QtCore.QRect(self.rect.width()-5.5,(self.rect.height()*1.44*x/(self.nop+1))-67,5,5), self, 'op',self.container) for x in range(1,self.nop+1)] + return Input,Output + elif(self.type=="MatStm"): + Input = [NodeSocket(QtCore.QRect(-2.5,(self.rect.height()*x/(self.nin+1))-1,4,4), self, 'in',self.container) for x in range(1,self.nin+1) ] + Output = [NodeSocket(QtCore.QRect(self.rect.width()-2.5,(self.rect.height()*x/(self.nin+1))-1,4,4), self, 'op',self.container) for x in range(1,self.nop+1)] + return Input,Output + + def mouseMoveEvent(self, event): + #print(event.scenePos()) + super(NodeItem, self).mouseMoveEvent(event) + for output in self.Output: + for line in output.outLines: + line.pointA = line.source.getCenter() + line.pointB = line.target.getCenter() + for input in self.Input: + for line in input.inLines: + line.pointA = line.source.getCenter() + line.pointB = line.target.getCenter() + self.pos = event.scenePos() + + def mouseDoubleClickEvent(self, event): + self.setPos(event.scenePos().x()-250,event.scenePos().y()) + self.dockWidget.show() + +def findMainWindow(self): + ''' + Global function to find the (open) QMainWindow in application + ''' + app = QApplication.instance() + for widget in app.topLevelWidgets(): + if isinstance(widget, QMainWindow): + return widget + return None |