-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMainWindowGUI.py
273 lines (223 loc) · 8.81 KB
/
MainWindowGUI.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
import pandas as pd
from PyQt5 import QtGui
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import *
from pandas import DataFrame as DataframeObject
import Dataframe
from GraphMenu import GraphMenu
from GraphModel import GraphModel
from LoadedSheets import LoadedSheets
from PandasModel import PandasModel
import sys
# Main window creation
class MainWindow(QMainWindow):
# Excel sheets
sheetsDir: LoadedSheets
# Tabs
tabs: QTabWidget
# Graph list
graph_window: list[QWidget]
# Dataframe list
data: list[DataframeObject]
# Graph menu
menu: list[GraphMenu]
def __init__(self, parent=None):
super().__init__(parent)
# Initialization
container = QWidget()
self.setCentralWidget(container)
layout = QGridLayout()
container.setLayout(layout)
self.sheetsDir = LoadedSheets(self)
self.tabs = QTabWidget(self)
self.data = []
self.menu = []
self.graph_window = []
# Set functions for click events
self.sheetsDir.loadedSheets.itemDoubleClicked.connect(self.loadSheet)
self.sheetsDir.saveButton.clicked.connect(self.save)
self.tabs.tabBarDoubleClicked.connect(self.del_tab)
# Add widgets to window
layout.addWidget(self.sheetsDir, 0, 0, 5, 2)
layout.addWidget(self.tabs, 0, 2, 5, 7)
# Window setup
self.setWindowTitle("Simple Cell")
self.setMinimumSize(1067, 600)
self.setWindowIcon(QtGui.QIcon('logo.jpg'))
self.show()
# Add tab to window
def add_tab(self, widget: QWidget, name):
tab = QWidget()
layout = QGridLayout()
tab.setLayout(layout)
layout.addWidget(widget, 0, 0)
# Add graph menu to tab
m = GraphMenu()
m.graph_type.currentIndexChanged.connect(self.set_combobox)
m.create.clicked.connect(self.create_graph)
layout.addWidget(m, 1, 0)
self.menu.append(m)
# Add tab
self.tabs.addTab(tab, name)
self.tabs.setCurrentIndex(len(self.tabs) - 1)
# Delete tab from double click
def del_tab(self):
if len(self.data) > 0:
tab_index = self.tabs.currentIndex()
self.tabs.removeTab(tab_index)
del self.menu[tab_index]
del self.data[tab_index]
# Load sheet
def loadSheet(self, file: QListWidgetItem):
# If sheet doesn't already exist, load it
if not self.tab_exists(file.text()):
excel_sheet_path = self.sheetsDir.getPath(file)
sheet = excel_sheet_path[excel_sheet_path.rfind(" - ") + 3:]
path = excel_sheet_path[:excel_sheet_path.rfind(" - ")]
# Create dataframe
df = Dataframe.excel_to_dataframe(path, sheet)
self.data.append(df)
df_model = self.create_dataframe_model(df)
self.add_tab(df_model, file.text())
df_cols = list(df.columns)
# Add dataframe columns to graph menu
for col in df_cols:
self.menu[len(self.menu) - 1].column1.addItem(col)
self.menu[len(self.menu) - 1].column2.addItem(col)
else:
return
# Check if tab already exists
def tab_exists(self, name):
tab_count = self.tabs.count()
if tab_count > 0:
for tab in range(0, self.tabs.count()):
if self.tabs.tabText(tab) == name:
return True
return False
else:
return False
# Create dataframe model for table widget
def create_dataframe_model(self, df: DataframeObject):
model = PandasModel(df)
view = QTableView()
view.setModel(model)
view.model().dataChanged.connect(self.changedData)
return view
# Create a graph
def create_graph(self):
# Get selected graph menu options
tab_index = self.tabs.currentIndex()
graph = GraphModel()
selected_graph = self.menu[tab_index].graph_type.currentText()
selected_col1 = self.menu[tab_index].column1.currentText()
selected_col2 = self.menu[tab_index].column2.currentText()
# Create line graph
if selected_graph == "Line" and selected_col1 != "Select Column 1":
try:
graph.axes.plot(self.data[tab_index][selected_col1])
self.create_graph_window(graph)
except Exception:
self.error_window()
return
# Create bar graph
elif selected_graph == "Bar" and selected_col1 != "Select Column 1" and \
selected_col2 != "Select Column 2":
try:
graph.axes.bar(self.data[tab_index][selected_col1], self.data[tab_index][selected_col2])
self.create_graph_window(graph)
except Exception:
self.error_window()
return
# If options are not correctly selected, don't make graph
else:
return
# Create new window for graph
def create_graph_window(self, graph):
# Create save button
save = QPushButton("Save as PNG")
layout = QGridLayout()
layout.addWidget(save, 0, 0)
layout.addWidget(graph, 1, 0)
tab_index = self.tabs.currentIndex()
selected_graph = self.menu[tab_index].graph_type.currentText()
selected_col1 = self.menu[tab_index].column1.currentText()
selected_col2 = self.menu[tab_index].column2.currentText()
w = QWidget()
w.setLayout(layout)
w.setWindowIcon(QtGui.QIcon('logo.jpg'))
# Set proper title
if selected_graph == "Line":
w.setWindowTitle("Line Graph [" + selected_col1 + "]")
elif selected_graph == "Bar":
w.setWindowTitle("Bar Graph [" + selected_col1 + ", " + selected_col2 + "]")
# Get click event for save graph
save.clicked.connect(self.save_graph)
self.graph_window.append(w)
self.graph_window[len(self.graph_window) - 1].show()
self.graph_window[len(self.graph_window) - 1].setMinimumSize(w.size())
# Save graph as png
def save_graph(self):
# Get graph and file name
graph = self.graph_window[len(self.graph_window) - 1].findChild(GraphModel)
file_name = self.graph_window[len(self.graph_window) - 1].windowTitle()
tab_index = self.tabs.currentIndex()
tab_title = self.tabs.tabText(tab_index)
path = self.sheetsDir.getPath(fileName=tab_title)
# Get correct path
last_char = path[-1]
while last_char != "/":
path = path[:-1]
last_char = path[-1]
# Save as png
graph.axes.figure.savefig(path + file_name + ".png")
# Error window that displays when graph creation throws error
def error_window(self):
error = QLabel("Graph Error: Unable to create graph\n\nCheck for bad data")
error.setAlignment(Qt.AlignCenter)
layout = QVBoxLayout()
layout.addWidget(error)
w = QWidget()
w.setLayout(layout)
w.setWindowTitle("Graph Error")
w.setFixedSize(300, 100)
w.setWindowIcon(QtGui.QIcon('logo.jpg'))
self.graph_window.append(w)
self.graph_window[len(self.graph_window) - 1].show()
# Enable or disable graph menu widgets accordingly
def set_combobox(self):
tab_index = self.tabs.currentIndex()
selected = self.menu[tab_index].graph_type.currentText()
if selected == "Line":
self.menu[tab_index].column1.setEnabled(True)
self.menu[tab_index].column2.setEnabled(False)
elif selected == "Bar":
self.menu[tab_index].column1.setEnabled(True)
self.menu[tab_index].column2.setEnabled(True)
else:
self.menu[tab_index].column1.setEnabled(False)
self.menu[tab_index].column2.setEnabled(False)
def changedData(self, item):
print(item.row())
print(item.column())
# Overwrite Excel file with edited data
def save(self):
tab_index = self.tabs.currentIndex()
if tab_index >= 0:
# Get path and file name
tab_title = self.tabs.tabText(tab_index)
path = self.sheetsDir.getPath(fileName=tab_title)
filename = path[:path.rfind(" - ")]
sheet = tab_title[tab_title.rfind(" - ") + 3:]
# Write to file
with pd.ExcelWriter(filename, engine='openpyxl', mode='a') as writer:
workBook = writer.book
try:
workBook.remove(workBook[sheet])
except:
print("Worksheet does not exist")
finally:
self.data[tab_index].to_excel(writer, sheet_name=sheet, index=False)
if __name__ == "__main__":
app = QApplication(sys.argv)
windowExample = MainWindow()
sys.exit(app.exec_())