개정판 2a9ea514
issue #1198: Loop 생성
Change-Id: I4e15ebfa4f5bccc349671541cbae68a70421d524
AppDatabase.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
""" This is AppDatabase module """ |
|
3 |
|
|
4 |
import sqlite3 |
|
5 |
import pymssql |
|
6 |
|
|
7 |
class AppDatabase: |
|
8 |
""" This is AppDatabase class """ |
|
9 |
def __init__(self, type, host, user, password, db_path): |
|
10 |
self._DBType = type |
|
11 |
self._host = host |
|
12 |
self._user = user |
|
13 |
self._password = password |
|
14 |
self._db_path = db_path |
|
15 |
|
|
16 |
@property |
|
17 |
def db_type(self): |
|
18 |
""" return database type """ |
|
19 |
return self._DBType |
|
20 |
|
|
21 |
@db_type.setter |
|
22 |
def db_type(self, value): |
|
23 |
self._DBType = value |
|
24 |
|
|
25 |
@property |
|
26 |
def host(self): |
|
27 |
""" return host for mssql """ |
|
28 |
return self._host |
|
29 |
|
|
30 |
@host.setter |
|
31 |
def host(self, value): |
|
32 |
self._host = value |
|
33 |
|
|
34 |
@property |
|
35 |
def user(self): |
|
36 |
""" return user for mssql """ |
|
37 |
return self._user |
|
38 |
|
|
39 |
@user.setter |
|
40 |
def user(self, value): |
|
41 |
self._user = value |
|
42 |
|
|
43 |
@property |
|
44 |
def password(self): |
|
45 |
""" return password for mssql """ |
|
46 |
return self._password |
|
47 |
|
|
48 |
@password.setter |
|
49 |
def password(self, value): |
|
50 |
self._password = value |
|
51 |
|
|
52 |
@property |
|
53 |
def db_name(self): |
|
54 |
""" return database name """ |
|
55 |
return self._db_path |
|
56 |
|
|
57 |
@property |
|
58 |
def file_path(self): |
|
59 |
""" return sqlite database file path """ |
|
60 |
return self._db_path |
|
61 |
|
|
62 |
@file_path.setter |
|
63 |
def file_path(self, value): |
|
64 |
self._db_path = value |
|
65 |
|
|
66 |
@property |
|
67 |
def place_holder(self): |
|
68 |
""" return database placeholder """ |
|
69 |
return '?' if self.db_type == 'SQLite' else '%s' if self.db_type == 'MSSQL' else None |
|
70 |
|
|
71 |
def connect(self): |
|
72 |
""" return database connection depends on database type """ |
|
73 |
conn = None |
|
74 |
if self._DBType == 'SQLite': |
|
75 |
conn = sqlite3.connect(self.file_path, isolation_level=None) |
|
76 |
conn.row_factory = sqlite3.Row |
|
77 |
#cursor = conn.cursor() |
|
78 |
elif self._DBType == 'MSSQL': |
|
79 |
conn = pymssql.connect(host=self._host, user=self._user, password=self._password, database=self.db_name, charset='utf8', autocommit=False) |
|
80 |
#cursor = conn.cursor(as_dic=True) |
|
81 |
|
|
82 |
return conn |
|
83 |
|
|
84 |
def to_sql(self, sql): |
|
85 |
""" convert given sql string for database """ |
|
86 |
|
|
87 |
return sql.replace('?', '%s') if self.db_type == "MSSQL" else sql |
HYTOS/HYTOS/Commands/HydroCalculationCommand.py | ||
---|---|---|
1 |
import os.path |
|
2 |
import sys |
|
3 |
import AbstractCommand |
|
4 |
try: |
|
5 |
from PyQt5.QtCore import * |
|
6 |
from PyQt5.QtGui import * |
|
7 |
from PyQt5.QtWidgets import * |
|
8 |
except ImportError: |
|
9 |
try: |
|
10 |
from PyQt4.QtCore import Qt, QPoint, QPointF, QRectF, pyqtSignal, QT_VERSION_STR, QMimeData |
|
11 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QColor, QPen, QBrush, QCursor |
|
12 |
except ImportError: |
|
13 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
14 |
|
|
15 |
class HydroCalculationCommand(AbstractCommand.AbstractCommand): |
|
16 |
""" Hydro Calculation class """ |
|
17 |
|
|
18 |
onSuccess = pyqtSignal(QGraphicsItem) |
|
19 |
|
|
20 |
def __init__(self, imageViewer): |
|
21 |
super(HydroCalculationCommand, self).__init__(imageViewer) |
|
22 |
self.name = 'HydroCalculation' |
|
23 |
|
|
24 |
self.loops = [] |
|
25 |
|
|
26 |
def execute(self, param): |
|
27 |
""" execute hydro calculation """ |
|
28 |
from EngineeringOriginItem import QEngineeringOriginItem |
|
29 |
from EngineeringGuidelineItem import QEngineeringGuidelineItem |
|
30 |
from SymbolSvgItem import SymbolSvgItem |
|
31 |
from EngineeringLoopItem import QEngineeringLoopItem |
|
32 |
|
|
33 |
queue = [] |
|
34 |
try: |
|
35 |
pressurized = [item for item in self.imageViewer.scene.items() if type(item) is SymbolSvgItem and item.category == 'Equipment - [ Pressurized ]'] |
|
36 |
for item in pressurized: |
|
37 |
matches = [conn for conn in item.connectors if conn.connectedItem and int(conn.connectedItem._conn_index) == 1] |
|
38 |
for match in matches: |
|
39 |
queue.append(QEngineeringLoopItem([match])) |
|
40 |
|
|
41 |
while queue: |
|
42 |
loop = queue.pop() |
|
43 |
queue.extend(self.make_loop(loop)) |
|
44 |
except Exception as ex: |
|
45 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
46 |
print('{}'.format(message)) |
|
47 |
|
|
48 |
def make_loop(self, loop): |
|
49 |
""" make a loop """ |
|
50 |
from EngineeringConnectorItem import QEngineeringConnectorItem |
|
51 |
from SymbolSvgItem import SymbolSvgItem |
|
52 |
from EngineeringStreamlineItem import QEngineeringStreamlineItem |
|
53 |
from EngineeringLoopItem import QEngineeringLoopItem |
|
54 |
|
|
55 |
res = [] |
|
56 |
|
|
57 |
try: |
|
58 |
while 1: |
|
59 |
if type(loop.items[-1]) is QEngineeringConnectorItem and type(loop.items[-1].parentItem()) is SymbolSvgItem: |
|
60 |
if loop.items[-1].connectedItem and int(loop.items[-1].connectedItem._conn_index) == 1: # start at connector |
|
61 |
loop.items.append(loop.items[-1].connectedItem.parentItem()) # it should be streamline |
|
62 |
if type(loop.items[-1]) is QEngineeringStreamlineItem: |
|
63 |
matches = [conn.connectedItem for conn in loop.items[-1].connectors if int(conn._conn_index) == 2 and conn.connectedItem] |
|
64 |
if matches: |
|
65 |
loop.items.append(matches[0]) |
|
66 |
else: |
|
67 |
break |
|
68 |
elif loop.items[-1].connectedItem and int(loop.items[-1].connectedItem._conn_index) == 2: # end at connector |
|
69 |
matches = [conn for conn in loop.items[-1].parentItem().connectors if (not conn in loop.items) and conn.connectedItem and int(conn.connectedItem._conn_index) == 1] |
|
70 |
if matches: |
|
71 |
for match in matches[1:]: |
|
72 |
res.append(QEngineeringLoopItem(loop.items + [match])) |
|
73 |
loop.items.append(matches[0]) |
|
74 |
else: |
|
75 |
break |
|
76 |
except Exception as ex: |
|
77 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
78 |
print('{}'.format(message)) |
|
79 |
finally: |
|
80 |
self.loops.append(loop) |
|
81 |
|
|
82 |
return res |
|
83 |
|
|
84 |
def undo(self): |
|
85 |
pass |
|
86 |
|
|
87 |
def redo(self): |
|
88 |
pass |
HYTOS/HYTOS/MainWindow.py | ||
---|---|---|
636 | 636 |
self.dlgOptions.exec_() |
637 | 637 |
|
638 | 638 |
def calculation(self): |
639 |
""" execute hydro calculation """ |
|
639 | 640 |
from AppDocData import AppDocData |
640 | 641 |
from Calculation import Calculation |
642 |
from HydroCalculationCommand import HydroCalculationCommand |
|
641 | 643 |
|
642 | 644 |
try: |
643 | 645 |
appDocData = AppDocData.instance() |
... | ... | |
664 | 666 |
self.progress.setValue(self.progress.value() + 1) |
665 | 667 |
|
666 | 668 |
if hmb.phase_type: |
667 |
Calculation(hmb)
|
|
669 |
Calculation(hmb) |
|
668 | 670 |
|
669 | 671 |
QApplication.processEvents() |
670 | 672 |
|
671 |
self.load_HMB() |
|
673 |
""" generate loop """ |
|
674 |
cmd = HydroCalculationCommand(self.graphicsView) |
|
675 |
cmd.execute(None) |
|
676 |
|
|
677 |
self.load_HMB() |
|
672 | 678 |
finally: |
673 | 679 |
self.progress.setValue(self.progress.maximum()) |
674 | 680 |
self.progress.hide() |
HYTOS/HYTOS/Shapes/EngineeringConnectorItem.py | ||
---|---|---|
59 | 59 |
self._spec_break = None |
60 | 60 |
self._connectedItem = None |
61 | 61 |
self._connected_at = QEngineeringAbstractItem.CONNECTED_AT_PT # default value is connected at pt |
62 |
self.sceneConnectPoint = None |
|
63 | 62 |
self.connectPoint = None |
64 | 63 |
self._hoverItem = None |
65 | 64 |
self._nozzle_data = None |
... | ... | |
73 | 72 |
""" setup label for connector index """ |
74 | 73 |
self._font = QFont('Arial', QEngineeringConnectorItem.SMALL_SIZE) |
75 | 74 |
self._font.setPointSizeF(5) |
76 |
self._conn_index = index |
|
75 |
|
|
76 |
self._conn_index = index |
|
77 |
|
|
78 |
def __repr__(self): |
|
79 |
""" return string represent parent item and connector index """ |
|
80 |
return '{}_N{}'.format(self.parentItem().name, self._conn_index) |
|
77 | 81 |
|
78 | 82 |
@staticmethod |
79 | 83 |
def find_connector(uid): |
... | ... | |
138 | 142 |
|
139 | 143 |
@property |
140 | 144 |
def symbol_idx(self): |
141 |
""" |
|
142 |
""" |
|
145 |
""" """ |
|
143 | 146 |
return self._symbol_idx |
144 | 147 |
|
145 | 148 |
@symbol_idx.setter |
146 | 149 |
def symbol_idx(self, value): |
147 |
""" |
|
148 |
setter of symbol_idx |
|
149 |
""" |
|
150 |
""" setter of symbol_idx """ |
|
150 | 151 |
self._symbol_idx = value |
151 | 152 |
|
152 | 153 |
@property |
153 | 154 |
def spec_break(self): |
154 |
""" |
|
155 |
getter of spec break |
|
156 |
""" |
|
155 |
""" getter of spec break """ |
|
157 | 156 |
return self._spec_break |
158 | 157 |
|
159 |
@spec_break.setter |
|
160 |
def spec_idx(self, value): |
|
161 |
""" |
|
162 |
setter of spec_break |
|
163 |
""" |
|
164 |
self._spec_break = value |
|
165 |
|
|
166 | 158 |
''' |
167 | 159 |
@brief return direction vector |
168 | 160 |
@author humkyung |
... | ... | |
180 | 172 |
|
181 | 173 |
return None |
182 | 174 |
|
183 |
def __repr__(self): |
|
184 |
return '{},{},{},{}'.format(self._direction, self.sceneConnectPoint[0], self.sceneConnectPoint[1] , self._symbol_idx) |
|
185 |
|
|
186 | 175 |
''' |
187 | 176 |
@brief build connector item |
188 | 177 |
@author humkyung |
HYTOS/HYTOS/Shapes/EngineeringLoopItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
import os.path |
|
3 |
import copy |
|
4 |
import sys |
|
5 |
try: |
|
6 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QObject, QT_VERSION_STR, QRect |
|
7 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont, QColor |
|
8 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsTextItem, QGraphicsRectItem |
|
9 |
except ImportError: |
|
10 |
try: |
|
11 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QRect, QObject, QT_VERSION_STR |
|
12 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont, QColor |
|
13 |
except ImportError: |
|
14 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
15 |
|
|
16 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
|
17 |
from AppDocData import * |
|
18 |
|
|
19 |
class QEngineeringLoopItem(QEngineeringAbstractItem): |
|
20 |
""" This is QEngineeringLoopItem class """ |
|
21 |
|
|
22 |
def __init__(self, _items): |
|
23 |
""" constructure """ |
|
24 |
import uuid |
|
25 |
|
|
26 |
QEngineeringAbstractItem.__init__(self) |
|
27 |
|
|
28 |
self._UID = None |
|
29 |
self._name = None |
|
30 |
self.items = _items |
|
31 |
|
|
32 |
def __repr__(self): |
|
33 |
""" return string represent loop item """ |
|
34 |
return '{}'.format(self.items) |
|
35 |
|
|
36 |
class Transfer(QObject): |
|
37 |
onRemoved = pyqtSignal(QGraphicsItem) |
|
38 |
|
|
39 |
def __init__(self, parent = None): |
|
40 |
QObject.__init__(self, parent) |
HYTOS/HYTOS/Shapes/EngineeringStreamlineItem.py | ||
---|---|---|
48 | 48 |
self._pt = None |
49 | 49 |
self.setPen(QPen(Qt.blue, 1, Qt.SolidLine)) # set default pen |
50 | 50 |
|
51 |
self._stream_no = QEngineeringStreamNoTextItem('<0>', self)
|
|
51 |
self._stream_no = QEngineeringStreamNoTextItem('0', self)
|
|
52 | 52 |
|
53 | 53 |
self.transfer = Transfer() |
54 | 54 |
self.transfer.onRemoved.connect(self.on_item_removed) |
... | ... | |
56 | 56 |
except Exception as ex: |
57 | 57 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
58 | 58 |
|
59 |
def __repr__(self): |
|
60 |
""" return string represents stream line item """ |
|
61 |
return 'Line_{}'.format(self._stream_no.toPlainText()) |
|
62 |
|
|
59 | 63 |
def build_connectors(self, connected, pointsUids=None): |
60 | 64 |
""" build connectors for stream line |
61 | 65 |
connected is target connector |
HYTOS/HYTOS/Shapes/TrainingBoxItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
import os.path |
|
3 |
import copy |
|
4 |
import sys |
|
5 |
try: |
|
6 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QObject, QT_VERSION_STR, QRect |
|
7 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont, QColor |
|
8 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsTextItem, QGraphicsRectItem |
|
9 |
except ImportError: |
|
10 |
try: |
|
11 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QRect, QObject, QT_VERSION_STR |
|
12 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont, QColor |
|
13 |
except ImportError: |
|
14 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
15 |
|
|
16 |
from EngineeringPolylineItem import QEngineeringPolylineItem |
|
17 |
from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem |
|
18 |
from AppDocData import * |
|
19 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
|
20 |
|
|
21 |
class QTrainingBoxItem(QGraphicsRectItem): |
|
22 |
def __init__(self, char, x, y, w, h, uid=None, parent=None): |
|
23 |
import uuid |
|
24 |
|
|
25 |
QGraphicsRectItem.__init__(self, x, y, w, h, parent) |
|
26 |
|
|
27 |
self.char = char |
|
28 |
self.uid = uuid.uuid4() if uid is None else uid |
|
29 |
|
|
30 |
self.setFlags(QGraphicsItem.ItemIsSelectable|QGraphicsItem.ItemIsFocusable) |
|
31 |
self.setAcceptHoverEvents(True) |
|
32 |
self.setAcceptTouchEvents(True) |
|
33 |
|
|
34 |
self.ui = None |
|
35 |
self.scene = None |
|
36 |
self.view = None |
|
37 |
self.leftSideView = None |
|
38 |
self.spinBoxFlag = None |
|
39 |
|
|
40 |
self.transfer = Transfer() |
|
41 |
#sung |
|
42 |
self.textShowBox = None |
|
43 |
|
|
44 |
def mousePressEvent(self, event): |
|
45 |
self.spinBoxFlag = True |
|
46 |
self.scene.clearSelection() |
|
47 |
#QGraphicsRectItem.mousePressEvent(self, event) |
|
48 |
self.setSelected(True) |
|
49 |
if self.textShowBox is not None: |
|
50 |
self.textShowBox.setSelected(True) |
|
51 |
|
|
52 |
rect = self.rect() |
|
53 |
self.ui.spinBoxLeft.setValue(round(rect.x())) |
|
54 |
self.ui.spinBoxTop.setValue(round(rect.y())) |
|
55 |
self.ui.spinBoxWidth.setValue(round(rect.width())) |
|
56 |
self.ui.spinBoxHeight.setValue(round(rect.height())) |
|
57 |
self.ui.lineEditChar.setText(self.char) |
|
58 |
|
|
59 |
rectSide = QRectF(rect.x() - 3, rect.y() - 3, rect.width() + 6, rect.height() + 6) |
|
60 |
bound = self.leftSideView.scene().items()[0] |
|
61 |
bound.setRect(rect) |
|
62 |
#self.leftSideView.fitInView(rectSide) |
|
63 |
self.spinBoxFlag = False |
|
64 |
|
|
65 |
def drawFocusRect(self, painter): |
|
66 |
pen = QPen(Qt.SolidLine) |
|
67 |
pen.setColor(Qt.blue) |
|
68 |
pen.setWidthF(1) |
|
69 |
pen.setJoinStyle(Qt.MiterJoin) |
|
70 |
painter.setPen(pen) |
|
71 |
painter.drawRect(self.boundingRect()) |
|
72 |
|
|
73 |
def paint(self, painter, options=None, widget=None): |
|
74 |
QGraphicsRectItem.paint(self, painter, options, widget) |
|
75 |
if self.isSelected(): |
|
76 |
self.drawFocusRect(painter) |
|
77 |
self.textShowBox.setDefaultTextColor(Qt.blue) |
|
78 |
else: |
|
79 |
self.textShowBox.setDefaultTextColor(Qt.green) |
|
80 |
|
|
81 |
def addTextItemToScene(self, ui, view, leftSideView, spinBoxFlag): |
|
82 |
try: |
|
83 |
self.ui = ui |
|
84 |
self.view = view |
|
85 |
self.scene = view.scene |
|
86 |
self.leftSideView = leftSideView |
|
87 |
self.spinBoxFlag = spinBoxFlag |
|
88 |
pen = QPen(Qt.SolidLine) |
|
89 |
pen.setColor(Qt.red) |
|
90 |
pen.setWidthF(1) |
|
91 |
pen.setJoinStyle(Qt.MiterJoin) |
|
92 |
self.setPen(pen) |
|
93 |
self.scene.addItem(self) |
|
94 |
|
|
95 |
self.textShowBox = QGraphicsTextItem(self.char) |
|
96 |
self.textShowBox.setFont(QFont('Consolas', 9, QFont.Bold)) |
|
97 |
self.textShowBox.setDefaultTextColor(Qt.green) |
|
98 |
self.textShowBox.setPos(self.rect().x() + round(self.rect().width() / 3), self.rect().y() - round(self.rect().height() / 2)) |
|
99 |
self.textShowBox.setParentItem(self) |
|
100 |
except Exception as ex: |
|
101 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
102 |
|
|
103 |
class Transfer(QObject): |
|
104 |
onRemoved = pyqtSignal(QGraphicsItem) |
|
105 |
|
|
106 |
def __init__(self, parent = None): |
|
107 |
QObject.__init__(self, parent) |
내보내기 Unified diff