개정판 c16dd916
add opc relation export function
Change-Id: Id382d96a72053f013ea52bfb05bf85cce41b3f16
DTI_PID/DTI_PID/CodeTableDialog.py | ||
---|---|---|
708 | 708 |
|
709 | 709 |
options = QFileDialog.Options() |
710 | 710 |
options |= QFileDialog.DontUseNativeDialog |
711 |
file_name, _ = QFileDialog.getSaveFileName(self, "Export code table", project.path, "xlsx files(*.xlsx)",
|
|
711 |
file_name, _ = QFileDialog.getSaveFileName(self, "Export Code Table", project.path, "xlsx files(*.xlsx)",
|
|
712 | 712 |
options=options) |
713 | 713 |
if not file_name: |
714 | 714 |
return |
DTI_PID/DTI_PID/OPCRelationDialog.py | ||
---|---|---|
7 | 7 |
from PyQt5.QtCore import * |
8 | 8 |
from PyQt5.QtGui import * |
9 | 9 |
from PyQt5.QtWidgets import * |
10 |
|
|
11 |
from openpyxl import * |
|
12 |
from openpyxl.styles import * |
|
13 |
|
|
10 | 14 |
from AppDocData import AppDocData, MessageType, Config |
11 | 15 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
12 | 16 |
|
... | ... | |
36 | 40 |
self.ui.pushButtonAutoFillClear.clicked.connect(self.on_auto_fill_clear_clicked) |
37 | 41 |
self.ui.pushButtonLineNoAttr.clicked.connect(self.on_line_no_target_clicked) |
38 | 42 |
self.ui.pushButtonSymbol.clicked.connect(self.on_symbol_target_clicked) |
43 |
self.ui.pushButtonExport.clicked.connect(self.on_save_excel) |
|
39 | 44 |
self.init_table_widget() |
40 | 45 |
|
41 | 46 |
def init_table_widget(self): |
... | ... | |
419 | 424 |
sys.exc_info()[-1].tb_lineno) |
420 | 425 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
421 | 426 |
|
427 |
def on_save_excel(self): |
|
428 |
"""export code table to excel file""" |
|
429 |
|
|
430 |
app_doc_data = AppDocData.instance() |
|
431 |
project = app_doc_data.getCurrentProject() |
|
432 |
|
|
433 |
options = QFileDialog.Options() |
|
434 |
options |= QFileDialog.DontUseNativeDialog |
|
435 |
file_name, _ = QFileDialog.getSaveFileName(self, "Export OPC Table", project.path, "xlsx files(*.xlsx)", |
|
436 |
options=options) |
|
437 |
if not file_name: |
|
438 |
return |
|
439 |
|
|
440 |
QApplication.setOverrideCursor(Qt.WaitCursor) |
|
441 |
|
|
442 |
try: |
|
443 |
wb = Workbook() |
|
444 |
wb.active.title = 'OPC Relation' |
|
445 |
|
|
446 |
sheet = wb.worksheets[0] |
|
447 |
self.set_sheet_header(self.ui.tableWidgetSource, sheet) |
|
448 |
self.fill_sheet_with_table(self.ui.tableWidgetSource, sheet) |
|
449 |
self.auto_resize_columns(sheet) |
|
450 |
|
|
451 |
file_name, ext = os.path.splitext(file_name) |
|
452 |
save_file_name = file_name + ext if ext.upper() == '.XLSX' else file_name + '.xlsx' |
|
453 |
wb.save(save_file_name) |
|
454 |
|
|
455 |
QMessageBox.about(self, self.tr("Information"), self.tr('Successfully saved.')) |
|
456 |
|
|
457 |
os.startfile(save_file_name) |
|
458 |
except Exception as ex: |
|
459 |
from App import App |
|
460 |
from AppDocData import MessageType |
|
461 |
|
|
462 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
463 |
sys.exc_info()[-1].tb_lineno) |
|
464 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
465 |
finally: |
|
466 |
QApplication.restoreOverrideCursor() |
|
467 |
|
|
468 |
def set_sheet_header(self, table, sheet): |
|
469 |
""" set list header """ |
|
470 |
|
|
471 |
try: |
|
472 |
thin = Side(border_style='thin', color='000000') |
|
473 |
border = Border(left=thin, right=thin, top=thin, bottom=thin) |
|
474 |
_col = 1 |
|
475 |
for col in range(table.columnCount()): |
|
476 |
logical_index = table.horizontalHeader().logicalIndex(col) |
|
477 |
col_name = table.horizontalHeaderItem(logical_index).text() |
|
478 |
sheet.cell(1, _col, col_name) |
|
479 |
sheet.cell(row=1, column=_col).alignment = Alignment(horizontal='center', vertical='center', |
|
480 |
wrapText=True) |
|
481 |
sheet.cell(row=1, column=_col).fill = PatternFill(patternType='solid', fill_type='solid', |
|
482 |
fgColor=Color('8DB4E2')) |
|
483 |
sheet.cell(row=1, column=_col).border = border |
|
484 |
_col += 1 |
|
485 |
except Exception as ex: |
|
486 |
from App import App |
|
487 |
from AppDocData import MessageType |
|
488 |
|
|
489 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
490 |
sys.exc_info()[-1].tb_lineno) |
|
491 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
492 |
|
|
493 |
def fill_sheet_with_table(self, table, sheet): |
|
494 |
"""fill sheet with table""" |
|
495 |
|
|
496 |
try: |
|
497 |
thin = Side(border_style='thin', color='000000') |
|
498 |
border = Border(left=thin, right=thin, top=thin, bottom=thin) |
|
499 |
|
|
500 |
for col in range(table.columnCount()): |
|
501 |
for row in range(table.rowCount()): |
|
502 |
try: |
|
503 |
text = str(table.item(row, col).text()) |
|
504 |
sheet.cell(row + 2, col + 1, text) |
|
505 |
sheet.cell(row=row + 2, column=col + 1).border = border |
|
506 |
except AttributeError: |
|
507 |
pass |
|
508 |
except Exception as ex: |
|
509 |
from App import App |
|
510 |
from AppDocData import MessageType |
|
511 |
|
|
512 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
513 |
sys.exc_info()[-1].tb_lineno) |
|
514 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
515 |
|
|
516 |
def auto_resize_columns(self, sheet): |
|
517 |
""" auto resize columns with contents """ |
|
518 |
|
|
519 |
from openpyxl.utils import get_column_letter |
|
520 |
try: |
|
521 |
for col in sheet.columns: |
|
522 |
max_length = 0 |
|
523 |
column = col[0].column # Get the column name |
|
524 |
for cell in col: |
|
525 |
try: # Necessary to avoid error on empty cells |
|
526 |
if len(str(cell.value)) > max_length: |
|
527 |
max_length = len(cell.value) |
|
528 |
except: |
|
529 |
pass |
|
530 |
|
|
531 |
adjusted_width = (max_length + 2) * 1.2 |
|
532 |
sheet.column_dimensions[get_column_letter(column) if type(column) is int else column].width = adjusted_width |
|
533 |
except Exception as ex: |
|
534 |
from App import App |
|
535 |
from AppDocData import MessageType |
|
536 |
|
|
537 |
message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
538 |
sys.exc_info()[-1].tb_lineno) |
|
539 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
540 |
|
|
422 | 541 |
def accept(self): |
423 | 542 |
""" save sql information to database """ |
424 | 543 |
from AppDocData import AppDocData |
DTI_PID/DTI_PID/UI/OPCRelation.ui | ||
---|---|---|
17 | 17 |
<bool>true</bool> |
18 | 18 |
</property> |
19 | 19 |
<layout class="QGridLayout" name="gridLayout"> |
20 |
<item row="0" column="0"> |
|
21 |
<layout class="QHBoxLayout" name="horizontalLayout"> |
|
22 |
<property name="sizeConstraint"> |
|
23 |
<enum>QLayout::SetFixedSize</enum> |
|
24 |
</property> |
|
25 |
<item> |
|
26 |
<widget class="QPushButton" name="pushButtonAutoFill"> |
|
27 |
<property name="maximumSize"> |
|
28 |
<size> |
|
29 |
<width>16777215</width> |
|
30 |
<height>20</height> |
|
31 |
</size> |
|
32 |
</property> |
|
33 |
<property name="text"> |
|
34 |
<string>Auto Fill</string> |
|
35 |
</property> |
|
36 |
</widget> |
|
37 |
</item> |
|
38 |
<item> |
|
39 |
<widget class="QPushButton" name="pushButtonAutoFillClear"> |
|
40 |
<property name="text"> |
|
41 |
<string>Auto Fill with Clear</string> |
|
42 |
</property> |
|
43 |
</widget> |
|
44 |
</item> |
|
45 |
<item> |
|
46 |
<spacer name="horizontalSpacer"> |
|
47 |
<property name="orientation"> |
|
48 |
<enum>Qt::Horizontal</enum> |
|
49 |
</property> |
|
50 |
<property name="sizeHint" stdset="0"> |
|
51 |
<size> |
|
52 |
<width>40</width> |
|
53 |
<height>20</height> |
|
54 |
</size> |
|
55 |
</property> |
|
56 |
</spacer> |
|
57 |
</item> |
|
58 |
<item> |
|
59 |
<widget class="QPushButton" name="pushButtonSymbol"> |
|
60 |
<property name="text"> |
|
61 |
<string>Symbol Setting</string> |
|
62 |
</property> |
|
63 |
</widget> |
|
64 |
</item> |
|
65 |
<item> |
|
66 |
<widget class="QPushButton" name="pushButtonLineNoAttr"> |
|
67 |
<property name="text"> |
|
68 |
<string>Line No. Key Setting</string> |
|
69 |
</property> |
|
70 |
</widget> |
|
71 |
</item> |
|
72 |
</layout> |
|
73 |
</item> |
|
74 |
<item row="3" column="0"> |
|
75 |
<widget class="QDialogButtonBox" name="buttonBox"> |
|
76 |
<property name="orientation"> |
|
77 |
<enum>Qt::Horizontal</enum> |
|
78 |
</property> |
|
79 |
<property name="standardButtons"> |
|
80 |
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> |
|
81 |
</property> |
|
82 |
</widget> |
|
83 |
</item> |
|
84 | 20 |
<item row="2" column="0"> |
85 | 21 |
<widget class="QSplitter" name="splitter"> |
86 | 22 |
<property name="sizePolicy"> |
... | ... | |
149 | 85 |
</widget> |
150 | 86 |
</widget> |
151 | 87 |
</item> |
88 |
<item row="0" column="0"> |
|
89 |
<layout class="QHBoxLayout" name="horizontalLayout"> |
|
90 |
<property name="sizeConstraint"> |
|
91 |
<enum>QLayout::SetFixedSize</enum> |
|
92 |
</property> |
|
93 |
<item> |
|
94 |
<widget class="QPushButton" name="pushButtonAutoFill"> |
|
95 |
<property name="maximumSize"> |
|
96 |
<size> |
|
97 |
<width>16777215</width> |
|
98 |
<height>20</height> |
|
99 |
</size> |
|
100 |
</property> |
|
101 |
<property name="text"> |
|
102 |
<string>Auto Fill</string> |
|
103 |
</property> |
|
104 |
</widget> |
|
105 |
</item> |
|
106 |
<item> |
|
107 |
<widget class="QPushButton" name="pushButtonAutoFillClear"> |
|
108 |
<property name="text"> |
|
109 |
<string>Auto Fill with Clear</string> |
|
110 |
</property> |
|
111 |
</widget> |
|
112 |
</item> |
|
113 |
<item> |
|
114 |
<spacer name="horizontalSpacer"> |
|
115 |
<property name="orientation"> |
|
116 |
<enum>Qt::Horizontal</enum> |
|
117 |
</property> |
|
118 |
<property name="sizeHint" stdset="0"> |
|
119 |
<size> |
|
120 |
<width>40</width> |
|
121 |
<height>20</height> |
|
122 |
</size> |
|
123 |
</property> |
|
124 |
</spacer> |
|
125 |
</item> |
|
126 |
<item> |
|
127 |
<widget class="QPushButton" name="pushButtonSymbol"> |
|
128 |
<property name="text"> |
|
129 |
<string>Symbol Setting</string> |
|
130 |
</property> |
|
131 |
</widget> |
|
132 |
</item> |
|
133 |
<item> |
|
134 |
<widget class="QPushButton" name="pushButtonLineNoAttr"> |
|
135 |
<property name="text"> |
|
136 |
<string>Line No. Key Setting</string> |
|
137 |
</property> |
|
138 |
</widget> |
|
139 |
</item> |
|
140 |
</layout> |
|
141 |
</item> |
|
142 |
<item row="3" column="0"> |
|
143 |
<layout class="QHBoxLayout" name="horizontalLayout_2"> |
|
144 |
<item> |
|
145 |
<widget class="QPushButton" name="pushButtonExport"> |
|
146 |
<property name="text"> |
|
147 |
<string>Export</string> |
|
148 |
</property> |
|
149 |
</widget> |
|
150 |
</item> |
|
151 |
<item> |
|
152 |
<spacer name="horizontalSpacer_2"> |
|
153 |
<property name="orientation"> |
|
154 |
<enum>Qt::Horizontal</enum> |
|
155 |
</property> |
|
156 |
<property name="sizeHint" stdset="0"> |
|
157 |
<size> |
|
158 |
<width>40</width> |
|
159 |
<height>20</height> |
|
160 |
</size> |
|
161 |
</property> |
|
162 |
</spacer> |
|
163 |
</item> |
|
164 |
<item> |
|
165 |
<widget class="QDialogButtonBox" name="buttonBox"> |
|
166 |
<property name="orientation"> |
|
167 |
<enum>Qt::Horizontal</enum> |
|
168 |
</property> |
|
169 |
<property name="standardButtons"> |
|
170 |
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> |
|
171 |
</property> |
|
172 |
</widget> |
|
173 |
</item> |
|
174 |
</layout> |
|
175 |
</item> |
|
152 | 176 |
</layout> |
153 | 177 |
</widget> |
154 | 178 |
<resources/> |
DTI_PID/DTI_PID/UI/OPCRelation_UI.py | ||
---|---|---|
2 | 2 |
|
3 | 3 |
# Form implementation generated from reading ui file './UI/OPCRelation.ui' |
4 | 4 |
# |
5 |
# Created by: PyQt5 UI code generator 5.9.2
|
|
5 |
# Created by: PyQt5 UI code generator 5.11.3
|
|
6 | 6 |
# |
7 | 7 |
# WARNING! All changes made in this file will be lost! |
8 | 8 |
|
... | ... | |
15 | 15 |
OPCRelationDialog.setSizeGripEnabled(True) |
16 | 16 |
self.gridLayout = QtWidgets.QGridLayout(OPCRelationDialog) |
17 | 17 |
self.gridLayout.setObjectName("gridLayout") |
18 |
self.horizontalLayout = QtWidgets.QHBoxLayout() |
|
19 |
self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize) |
|
20 |
self.horizontalLayout.setObjectName("horizontalLayout") |
|
21 |
self.pushButtonAutoFill = QtWidgets.QPushButton(OPCRelationDialog) |
|
22 |
self.pushButtonAutoFill.setMaximumSize(QtCore.QSize(16777215, 20)) |
|
23 |
self.pushButtonAutoFill.setObjectName("pushButtonAutoFill") |
|
24 |
self.horizontalLayout.addWidget(self.pushButtonAutoFill) |
|
25 |
self.pushButtonAutoFillClear = QtWidgets.QPushButton(OPCRelationDialog) |
|
26 |
self.pushButtonAutoFillClear.setObjectName("pushButtonAutoFillClear") |
|
27 |
self.horizontalLayout.addWidget(self.pushButtonAutoFillClear) |
|
28 |
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) |
|
29 |
self.horizontalLayout.addItem(spacerItem) |
|
30 |
self.pushButtonSymbol = QtWidgets.QPushButton(OPCRelationDialog) |
|
31 |
self.pushButtonSymbol.setObjectName("pushButtonSymbol") |
|
32 |
self.horizontalLayout.addWidget(self.pushButtonSymbol) |
|
33 |
self.pushButtonLineNoAttr = QtWidgets.QPushButton(OPCRelationDialog) |
|
34 |
self.pushButtonLineNoAttr.setObjectName("pushButtonLineNoAttr") |
|
35 |
self.horizontalLayout.addWidget(self.pushButtonLineNoAttr) |
|
36 |
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1) |
|
37 |
self.buttonBox = QtWidgets.QDialogButtonBox(OPCRelationDialog) |
|
38 |
self.buttonBox.setOrientation(QtCore.Qt.Horizontal) |
|
39 |
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) |
|
40 |
self.buttonBox.setObjectName("buttonBox") |
|
41 |
self.gridLayout.addWidget(self.buttonBox, 3, 0, 1, 1) |
|
42 | 18 |
self.splitter = QtWidgets.QSplitter(OPCRelationDialog) |
43 | 19 |
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) |
44 | 20 |
sizePolicy.setHorizontalStretch(0) |
... | ... | |
74 | 50 |
self.tableWidgetTarget.setRowCount(0) |
75 | 51 |
self.tableWidgetTarget.horizontalHeader().setStretchLastSection(True) |
76 | 52 |
self.gridLayout.addWidget(self.splitter, 2, 0, 1, 1) |
53 |
self.horizontalLayout = QtWidgets.QHBoxLayout() |
|
54 |
self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize) |
|
55 |
self.horizontalLayout.setObjectName("horizontalLayout") |
|
56 |
self.pushButtonAutoFill = QtWidgets.QPushButton(OPCRelationDialog) |
|
57 |
self.pushButtonAutoFill.setMaximumSize(QtCore.QSize(16777215, 20)) |
|
58 |
self.pushButtonAutoFill.setObjectName("pushButtonAutoFill") |
|
59 |
self.horizontalLayout.addWidget(self.pushButtonAutoFill) |
|
60 |
self.pushButtonAutoFillClear = QtWidgets.QPushButton(OPCRelationDialog) |
|
61 |
self.pushButtonAutoFillClear.setObjectName("pushButtonAutoFillClear") |
|
62 |
self.horizontalLayout.addWidget(self.pushButtonAutoFillClear) |
|
63 |
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) |
|
64 |
self.horizontalLayout.addItem(spacerItem) |
|
65 |
self.pushButtonSymbol = QtWidgets.QPushButton(OPCRelationDialog) |
|
66 |
self.pushButtonSymbol.setObjectName("pushButtonSymbol") |
|
67 |
self.horizontalLayout.addWidget(self.pushButtonSymbol) |
|
68 |
self.pushButtonLineNoAttr = QtWidgets.QPushButton(OPCRelationDialog) |
|
69 |
self.pushButtonLineNoAttr.setObjectName("pushButtonLineNoAttr") |
|
70 |
self.horizontalLayout.addWidget(self.pushButtonLineNoAttr) |
|
71 |
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1) |
|
72 |
self.horizontalLayout_2 = QtWidgets.QHBoxLayout() |
|
73 |
self.horizontalLayout_2.setObjectName("horizontalLayout_2") |
|
74 |
self.pushButtonExport = QtWidgets.QPushButton(OPCRelationDialog) |
|
75 |
self.pushButtonExport.setObjectName("pushButtonExport") |
|
76 |
self.horizontalLayout_2.addWidget(self.pushButtonExport) |
|
77 |
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) |
|
78 |
self.horizontalLayout_2.addItem(spacerItem1) |
|
79 |
self.buttonBox = QtWidgets.QDialogButtonBox(OPCRelationDialog) |
|
80 |
self.buttonBox.setOrientation(QtCore.Qt.Horizontal) |
|
81 |
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok) |
|
82 |
self.buttonBox.setObjectName("buttonBox") |
|
83 |
self.horizontalLayout_2.addWidget(self.buttonBox) |
|
84 |
self.gridLayout.addLayout(self.horizontalLayout_2, 3, 0, 1, 1) |
|
77 | 85 |
|
78 | 86 |
self.retranslateUi(OPCRelationDialog) |
79 | 87 |
self.buttonBox.accepted.connect(OPCRelationDialog.accept) |
... | ... | |
83 | 91 |
def retranslateUi(self, OPCRelationDialog): |
84 | 92 |
_translate = QtCore.QCoreApplication.translate |
85 | 93 |
OPCRelationDialog.setWindowTitle(_translate("OPCRelationDialog", "OPC Relation")) |
94 |
self.tableWidgetSource.setSortingEnabled(True) |
|
95 |
self.tableWidgetTarget.setSortingEnabled(True) |
|
86 | 96 |
self.pushButtonAutoFill.setText(_translate("OPCRelationDialog", "Auto Fill")) |
87 | 97 |
self.pushButtonAutoFillClear.setText(_translate("OPCRelationDialog", "Auto Fill with Clear")) |
88 | 98 |
self.pushButtonSymbol.setText(_translate("OPCRelationDialog", "Symbol Setting")) |
89 | 99 |
self.pushButtonLineNoAttr.setText(_translate("OPCRelationDialog", "Line No. Key Setting")) |
90 |
self.tableWidgetSource.setSortingEnabled(True) |
|
91 |
self.tableWidgetTarget.setSortingEnabled(True) |
|
100 |
self.pushButtonExport.setText(_translate("OPCRelationDialog", "Export")) |
|
92 | 101 |
|
93 | 102 |
|
94 | 103 |
if __name__ == "__main__": |
내보내기 Unified diff