hytos / DTI_PID / DTI_PID / BMSettingDialog.py @ 54be6611
이력 | 보기 | 이력해설 | 다운로드 (17.5 KB)
1 |
# coding: utf-8
|
---|---|
2 |
"""
|
3 |
This is area configuration module
|
4 |
"""
|
5 |
import os |
6 |
import sys |
7 |
from PyQt5.QtCore import * |
8 |
from PyQt5.QtGui import * |
9 |
from PyQt5.QtWidgets import * |
10 |
from functools import reduce, partial |
11 |
from AppDocData import AppDocData, Config |
12 |
|
13 |
import BMSetting_UI |
14 |
|
15 |
class AttributeListModel(QStandardItemModel): |
16 |
def __init__(self, columListAll, parent=None, *args): |
17 |
QStandardItemModel.__init__(self, parent, *args)
|
18 |
|
19 |
self.columListAll = columListAll
|
20 |
|
21 |
for symbol in sorted(self.columListAll): |
22 |
items = [QStandardItem(symbol)] |
23 |
items[0].setEditable(False) |
24 |
self.appendRow(items)
|
25 |
|
26 |
headers = [QStandardItem("Name"), QStandardItem("State")] |
27 |
for idx, header in enumerate(headers): |
28 |
header.setTextAlignment(Qt.AlignCenter) |
29 |
self.setHorizontalHeaderItem(idx, header)
|
30 |
|
31 |
class SymbolListModel(QStandardItemModel): |
32 |
def __init__(self, parent=None, *args): |
33 |
QStandardItemModel.__init__(self, parent, *args)
|
34 |
|
35 |
self.SymbolList = [ "CAP", "DRAIN CUP", "EOL", "FLANGE", "FLANGE BLIND", "MONOFLANGE", "ORIFICE", "PLUG", "SCREW CAP", |
36 |
"3WAY", "4WAY", "ANGLE", "BALL", "BUTTERFLY", "CHECK", "DIAPHRAMVALVE", "GATE", "GLOBE", "NEEDLE", "VALVEPLUG", |
37 |
"CONTROL(ANGLE)", "CONTROL(BALL)", "CONTROL(BUTTERFLY)", "CONTROL(CHECK)", "CONTROL(GATE)", "CONTROL(GLOBE)", "CONTROL(NEEDLE)", "CONTROL(PLUG)", |
38 |
"MOV(ANGLE)", "MOV(BALL)", "MOV(BUTTERFLY)", "MOV(CHECK)", "MOV(GATE)", "MOV(GLOBE)", "MOV(NEEDLE)", "MOV(PLUG)", "CORIOLIS FLOW METER", "MAGNETIC FLOW METER", "MASS FLOW METER", "ULTRASONIC FLOW METER", "VORTEX FLOW METER", "OPC", |
39 |
"AIR TRAP", "TRAP", "GOOSE NECK VENT", "VENT", "SCREEN", "IP", "PG", "PP", "PSV", "RE", "RS", "SEAL", "EXPANSION JOINT", "FA", "SAMPLE CONNECTION", "SB", "SPACER", "STRAINER", "T STRAINER", "Y STRAINER", "BUCKET STRAINER", "CONE STRAINER", "TG", "HOSE CONNECTION", "OD" ] |
40 |
|
41 |
for symbol in self.SymbolList: |
42 |
items = [QStandardItem(symbol)] |
43 |
items[0].setEditable(False) |
44 |
self.appendRow(items)
|
45 |
|
46 |
app_doc_data = AppDocData.instance() |
47 |
configs = app_doc_data.getConfigs(section='BM Symbol')
|
48 |
|
49 |
for config in configs: |
50 |
if config.key not in self.SymbolList: |
51 |
items = [QStandardItem(config.key)] |
52 |
items[0].setEditable(False) |
53 |
self.appendRow(items)
|
54 |
|
55 |
headers = [QStandardItem("Name")]
|
56 |
for idx, header in enumerate(headers): |
57 |
header.setTextAlignment(Qt.AlignCenter) |
58 |
self.setHorizontalHeaderItem(idx, header)
|
59 |
|
60 |
class SymbolMappingModel(QStandardItemModel): |
61 |
"""This is SymbolMapping Model class"""
|
62 |
def __init__(self): |
63 |
"""constructor"""
|
64 |
QStandardItemModel.__init__(self)
|
65 |
|
66 |
app_doc_data = AppDocData.instance() |
67 |
project = app_doc_data.getCurrentProject() |
68 |
if project is not None: |
69 |
self.clear()
|
70 |
self.load_symbol_info()
|
71 |
|
72 |
headers = [QStandardItem("Name"), QStandardItem("State")] |
73 |
for idx, header in enumerate(headers): |
74 |
header.setTextAlignment(Qt.AlignCenter) |
75 |
self.setHorizontalHeaderItem(idx, header)
|
76 |
|
77 |
def load_symbol_info(self): |
78 |
"""load symbol information and display it on tree view"""
|
79 |
try:
|
80 |
app_doc_data = AppDocData.instance() |
81 |
|
82 |
symbolTypeList = app_doc_data.getSymbolTypeList() |
83 |
for row, symbolType in enumerate(symbolTypeList): |
84 |
items = [QStandardItem(symbolType[2]), QStandardItem('')] |
85 |
items[0].setData(symbolType, Qt.UserRole)
|
86 |
items[0].setEditable(False) |
87 |
items[0].setSelectable(False) |
88 |
items[1].setEditable(False) |
89 |
items[1].setSelectable(False) |
90 |
|
91 |
symbolList = app_doc_data.getSymbolListByType('UID', symbolType[0]) |
92 |
for symbol in symbolList: |
93 |
childs = [QStandardItem(symbol.getName()), QStandardItem('')]
|
94 |
childs[0].setData(symbol.getUid(), Qt.UserRole)
|
95 |
childs[0].setEditable(False) |
96 |
|
97 |
_, svg = app_doc_data.read_symbol_shape(symbol.sName) |
98 |
if svg:
|
99 |
symbol.pixmap = QPixmap() |
100 |
symbol.pixmap.loadFromData(svg if isinstance(svg, bytes) else svg.encode()) |
101 |
icon = QIcon(symbol.pixmap) |
102 |
childs[0].setIcon(icon)
|
103 |
childs[0].svgFilePath = None # save svg file path |
104 |
else:
|
105 |
svgPath = symbol.getSvgFileFullPath() |
106 |
symbol.pixmap = QPixmap(svgPath) |
107 |
icon = QIcon(symbol.pixmap) |
108 |
childs[0].setIcon(icon)
|
109 |
childs[0].svgFilePath = svgPath # save svg file path |
110 |
|
111 |
items[0].appendRow(childs)
|
112 |
|
113 |
items[0].sortChildren(0, Qt.AscendingOrder) |
114 |
self.appendRow(items)
|
115 |
except Exception as ex: |
116 |
from App import App |
117 |
from AppDocData import MessageType |
118 |
|
119 |
message = f'error occurred({ex}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:' \
|
120 |
f'{sys.exc_info()[-1].tb_lineno}'
|
121 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
122 |
|
123 |
|
124 |
class BMSettingDialog(QDialog): |
125 |
def __init__(self, parent, columListAll): |
126 |
QDialog.__init__(self, parent)
|
127 |
|
128 |
self.ui = BMSetting_UI.Ui_BMSettingDialog()
|
129 |
self.ui.setupUi(self) |
130 |
|
131 |
self.delimiter = '!-!' |
132 |
self.delimiterCombine = '!@!' |
133 |
|
134 |
self.isAccepted = False |
135 |
self.symbol_mapping = {}
|
136 |
self.attributes = []
|
137 |
self.columListAll = columListAll
|
138 |
|
139 |
self.symbolListModel = SymbolListModel()
|
140 |
self.ui.tableViewSymbolList.setModel(self.symbolListModel) |
141 |
|
142 |
# for test
|
143 |
'''
|
144 |
self.lineEdit = QLineEdit()
|
145 |
self.comboBox = QComboBox()
|
146 |
|
147 |
self.ui.gridLayout_3.addWidget(self.lineEdit, 0, 1, 1, 1)
|
148 |
self.ui.gridLayout_3.addWidget(self.comboBox, 0, 2, 1, 1)
|
149 |
|
150 |
self.proxy = QSortFilterProxyModel(self)
|
151 |
self.proxy.setSourceModel(self.symbolListModel)
|
152 |
self.ui.tableViewSymbolList.setModel(self.proxy)
|
153 |
|
154 |
self.comboBox.addItems(["Column {0}".format(x) for x in range(self.symbolListModel.columnCount())])
|
155 |
|
156 |
self.lineEdit.textChanged.connect(self.on_lineEdit_textChanged)
|
157 |
self.comboBox.currentIndexChanged.connect(self.on_comboBox_currentIndexChanged)
|
158 |
|
159 |
self.horizontalHeader = self.ui.tableViewSymbolList.horizontalHeader()
|
160 |
self.horizontalHeader.sectionClicked.connect(self.on_view_horizontalHeader_sectionClicked)
|
161 |
'''
|
162 |
# uo to here
|
163 |
|
164 |
self.symbolMappingModel = SymbolMappingModel()
|
165 |
self.symbolMappingModel.invisibleRootItem()
|
166 |
self.ui.treeViewSymbolMapping.setModel(self.symbolMappingModel) |
167 |
self.ui.treeViewSymbolMapping.expandAll()
|
168 |
|
169 |
self.attributeListModel = AttributeListModel(self.columListAll) |
170 |
self.ui.tableViewAttributeList.setModel(self.attributeListModel) |
171 |
|
172 |
self.add_check_box()
|
173 |
self.load_BM_setting()
|
174 |
|
175 |
self.ui.tableViewSymbolList.horizontalHeader().setStretchLastSection(True) |
176 |
self.ui.treeViewSymbolMapping.header().setStretchLastSection(True) |
177 |
self.ui.tableViewAttributeList.horizontalHeader().setStretchLastSection(True) |
178 |
self.ui.tableViewSymbolList.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
|
179 |
self.ui.treeViewSymbolMapping.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
|
180 |
self.ui.tableViewAttributeList.setSizeAdjustPolicy(QAbstractScrollArea.AdjustToContents)
|
181 |
self.ui.treeViewSymbolMapping.resizeColumnToContents(0) |
182 |
self.ui.treeViewSymbolMapping.setColumnWidth(1, 50) |
183 |
self.ui.tableViewSymbolList.resizeColumnsToContents()
|
184 |
self.ui.tableViewAttributeList.resizeColumnsToContents()
|
185 |
self.ui.tableViewAttributeList.setColumnWidth(1, 50) |
186 |
|
187 |
self.ui.tableViewSymbolList.clicked.connect(self.on_symbol_changed) |
188 |
self.ui.pushButtonAdd.clicked.connect(self.on_add_symbol) |
189 |
self.ui.pushButtonDelete.clicked.connect(self.on_delete_symbol) |
190 |
self.ui.buttonBox.accepted.connect(self.accept) |
191 |
self.ui.buttonBox.rejected.connect(self.reject) |
192 |
|
193 |
self.ui.tableViewSymbolList.selectionModel().setCurrentIndex(self.symbolListModel.index(0, 0), QItemSelectionModel.Select) |
194 |
|
195 |
# for test
|
196 |
#self.on_symbol_changed(self.proxy.index(0, 0))
|
197 |
self.on_symbol_changed(self.symbolListModel.index(0, 0)) |
198 |
|
199 |
# for test
|
200 |
'''
|
201 |
@pyqtSlot(int)
|
202 |
def on_view_horizontalHeader_sectionClicked(self, logicalIndex):
|
203 |
self.logicalIndex = logicalIndex
|
204 |
self.menuValues = QMenu(self)
|
205 |
self.signalMapper = QSignalMapper(self)
|
206 |
|
207 |
self.comboBox.blockSignals(True)
|
208 |
self.comboBox.setCurrentIndex(self.logicalIndex)
|
209 |
self.comboBox.blockSignals(True)
|
210 |
|
211 |
valuesUnique = [self.symbolListModel.item(row, self.logicalIndex).text() for row in range(self.symbolListModel.rowCount())]
|
212 |
|
213 |
actionAll = QAction("All", self)
|
214 |
actionAll.triggered.connect(self.on_actionAll_triggered)
|
215 |
self.menuValues.addAction(actionAll)
|
216 |
self.menuValues.addSeparator()
|
217 |
|
218 |
for actionNumber, actionName in enumerate(sorted(list(set(valuesUnique)))):
|
219 |
action = QAction(actionName, self)
|
220 |
self.signalMapper.setMapping(action, actionNumber)
|
221 |
action.triggered.connect(self.signalMapper.map)
|
222 |
self.menuValues.addAction(action)
|
223 |
|
224 |
self.signalMapper.mapped.connect(self.on_signalMapper_mapped)
|
225 |
|
226 |
headerPos = self.ui.tableViewSymbolList.mapToGlobal(self.horizontalHeader.pos())
|
227 |
|
228 |
posY = headerPos.y() + self.horizontalHeader.height()
|
229 |
posX = headerPos.x() + self.horizontalHeader.sectionPosition(self.logicalIndex)
|
230 |
|
231 |
self.menuValues.exec_(QPoint(posX, posY))
|
232 |
|
233 |
@pyqtSlot()
|
234 |
def on_actionAll_triggered(self):
|
235 |
filterColumn = self.logicalIndex
|
236 |
filterString = QRegExp("", Qt.CaseInsensitive, QRegExp.RegExp)
|
237 |
|
238 |
self.proxy.setFilterRegExp(filterString)
|
239 |
self.proxy.setFilterKeyColumn(filterColumn)
|
240 |
|
241 |
@pyqtSlot(int)
|
242 |
def on_signalMapper_mapped(self, i):
|
243 |
stringAction = self.signalMapper.mapping(i).text()
|
244 |
filterColumn = self.logicalIndex
|
245 |
filterString = QRegExp(stringAction, Qt.CaseSensitive, QRegExp.FixedString)
|
246 |
|
247 |
self.proxy.setFilterRegExp(filterString)
|
248 |
self.proxy.setFilterKeyColumn(filterColumn)
|
249 |
|
250 |
@pyqtSlot(str)
|
251 |
def on_lineEdit_textChanged(self, text):
|
252 |
search = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp)
|
253 |
|
254 |
self.proxy.setFilterRegExp(search)
|
255 |
|
256 |
@pyqtSlot(int)
|
257 |
def on_comboBox_currentIndexChanged(self, index):
|
258 |
self.proxy.setFilterKeyColumn(index)
|
259 |
'''
|
260 |
# up to here
|
261 |
|
262 |
def on_add_symbol(self): |
263 |
from BMSymbolAddDialog import QBMSymbolAddDialog |
264 |
|
265 |
dialog = QBMSymbolAddDialog(self, list(self.symbol_mapping.keys())) |
266 |
isAccepted, name = dialog.showDialog() |
267 |
if isAccepted:
|
268 |
items = [QStandardItem(name)] |
269 |
items[0].setEditable(False) |
270 |
self.symbolListModel.appendRow(items)
|
271 |
self.symbol_mapping[name] = []
|
272 |
|
273 |
def on_delete_symbol(self): |
274 |
index = self.ui.tableViewSymbolList.currentIndex()
|
275 |
selected_symbol = self.symbolListModel.itemFromIndex(index)
|
276 |
if selected_symbol.text() not in self.symbolListModel.SymbolList: |
277 |
self.symbol_mapping.pop(selected_symbol.text())
|
278 |
self.symbolListModel.removeRow(index.row())
|
279 |
|
280 |
def load_BM_setting(self): |
281 |
app_doc_data = AppDocData.instance() |
282 |
|
283 |
for symbol in self.symbolListModel.SymbolList: |
284 |
self.symbol_mapping[symbol] = []
|
285 |
|
286 |
configs = app_doc_data.getConfigs(section='BM Symbol')
|
287 |
|
288 |
for config in configs: |
289 |
self.symbol_mapping[config.key] = config.value.split(',') |
290 |
|
291 |
configs = app_doc_data.getConfigs(section='Order', key='BM_LIST') |
292 |
if configs and len(configs) == 1: |
293 |
self.attributes = [attr.split(self.delimiterCombine)[0] for attr in configs[0].value.split(self.delimiter)] |
294 |
|
295 |
for row in range(self.attributeListModel.rowCount()): |
296 |
index = self.attributeListModel.index(row, 1) |
297 |
attr_index = self.attributeListModel.index(row, 0) |
298 |
attr = self.attributeListModel.itemFromIndex(attr_index).text()
|
299 |
if attr in self.attributes: |
300 |
checkBox = self.ui.tableViewAttributeList.indexWidget(index)
|
301 |
checkBox.setCheckState(Qt.Checked) |
302 |
|
303 |
def add_check_box(self): |
304 |
for row in range(self.symbolMappingModel.rowCount()): |
305 |
parent_index = self.symbolMappingModel.index(row, 0) |
306 |
child_count = self.symbolMappingModel.rowCount(parent_index)
|
307 |
for child_row in range(child_count): |
308 |
checkBox = QCheckBox() |
309 |
index = self.symbolMappingModel.index(child_row, 1, parent_index) |
310 |
symbol_index = self.symbolMappingModel.index(child_row, 0, parent_index) |
311 |
symbol_id = self.symbolMappingModel.itemFromIndex(symbol_index).data(Qt.UserRole)
|
312 |
checkBox.stateChanged.connect(partial(self.on_symbol_checkBox_changed, str(symbol_id))) |
313 |
self.ui.treeViewSymbolMapping.setIndexWidget(index, checkBox)
|
314 |
|
315 |
for row in range(self.attributeListModel.rowCount()): |
316 |
index = self.attributeListModel.index(row, 1) |
317 |
checkBox = QCheckBox() |
318 |
attr_index = self.attributeListModel.index(row, 0) |
319 |
attr = self.attributeListModel.itemFromIndex(attr_index).text()
|
320 |
checkBox.stateChanged.connect(partial(self.on_attribute_checkBox_changed, attr))
|
321 |
self.ui.tableViewAttributeList.setIndexWidget(index, checkBox)
|
322 |
|
323 |
def on_symbol_checkBox_changed(self, symbol_id, checkState): |
324 |
# for test
|
325 |
#index = self.ui.tableViewSymbolList.currentIndex()
|
326 |
#source_index = self.proxy.mapToSource(self.proxy.index(index.row(), index.column()))
|
327 |
#selected_symbol = self.symbolListModel.itemFromIndex(source_index)
|
328 |
# up to here
|
329 |
|
330 |
index = self.ui.tableViewSymbolList.currentIndex()
|
331 |
selected_symbol = self.symbolListModel.itemFromIndex(index)
|
332 |
|
333 |
if checkState is int(Qt.Checked) and not symbol_id in self.symbol_mapping[selected_symbol.text()]: |
334 |
self.symbol_mapping[selected_symbol.text()].append(symbol_id)
|
335 |
elif checkState is int(Qt.Unchecked) and symbol_id in self.symbol_mapping[selected_symbol.text()]: |
336 |
self.symbol_mapping[selected_symbol.text()].remove(symbol_id)
|
337 |
|
338 |
def on_attribute_checkBox_changed(self, attr, checkState): |
339 |
if checkState is int(Qt.Checked) and not attr in self.attributes: |
340 |
self.attributes.append(attr)
|
341 |
elif checkState is int(Qt.Unchecked) and attr in self.attributes: |
342 |
self.attributes.remove(attr)
|
343 |
|
344 |
def on_symbol_changed(self, index): |
345 |
# for test
|
346 |
#source_index = self.proxy.mapToSource(index)
|
347 |
#selected_symbol = self.symbolListModel.itemFromIndex(source_index)
|
348 |
# up to here
|
349 |
|
350 |
selected_symbol = self.symbolListModel.itemFromIndex(index)
|
351 |
|
352 |
for row in range(self.symbolMappingModel.rowCount()): |
353 |
category_index = self.symbolMappingModel.index(row, 0) |
354 |
|
355 |
child_count = self.symbolMappingModel.rowCount(category_index)
|
356 |
for child_row in range(child_count): |
357 |
child_index = self.symbolMappingModel.index(child_row, 0, category_index) |
358 |
id2_symbol_item = self.symbolMappingModel.itemFromIndex(child_index)
|
359 |
id2_symbol_uid = str(id2_symbol_item.data(Qt.UserRole))
|
360 |
checkBox_index = self.symbolMappingModel.index(child_row, 1, category_index) |
361 |
checkBox = self.ui.treeViewSymbolMapping.indexWidget(checkBox_index)
|
362 |
checkBox.setEnabled(True)
|
363 |
if id2_symbol_uid in self.symbol_mapping[selected_symbol.text()]: |
364 |
checkBox.setCheckState(Qt.Checked) |
365 |
else:
|
366 |
checkBox.setCheckState(Qt.Unchecked) |
367 |
|
368 |
matches = [key for key, value in self.symbol_mapping.items() if id2_symbol_uid in value] # key != id2_symbol_item.text() and |
369 |
if matches:
|
370 |
checkBox.setEnabled(False)
|
371 |
|
372 |
def reject(self): |
373 |
QDialog.reject(self)
|
374 |
|
375 |
def accept(self): |
376 |
try:
|
377 |
app_doc_data = AppDocData.instance() |
378 |
|
379 |
configs = [] |
380 |
for key, value in self.symbol_mapping.items(): |
381 |
if value:
|
382 |
configs.append(Config('BM Symbol', key, ','.join(value))) |
383 |
|
384 |
#self.attributes = ['UID', 'ITEM_NO', 'Quantity'] + self.attributes
|
385 |
configs.append(Config('Order', 'BM_LIST', self.delimiter.join([attr + self.delimiterCombine + attr for attr in self.attributes]))) |
386 |
|
387 |
app_doc_data.deleteConfigs(section='BM Symbol')
|
388 |
app_doc_data.deleteConfigs(section='Order', key='BM_LIST') |
389 |
|
390 |
app_doc_data.saveConfigs(configs) |
391 |
|
392 |
self.isAccepted = True |
393 |
QDialog.accept(self)
|
394 |
|
395 |
except Exception as ex: |
396 |
from App import App |
397 |
from AppDocData import MessageType |
398 |
|
399 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
400 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
401 |
|
402 |
def showDialog(self): |
403 |
self.setWindowFlags(self.windowFlags() & ~Qt.WindowCloseButtonHint & ~Qt.WindowContextHelpButtonHint) |
404 |
self.exec_()
|
405 |
return self.isAccepted |