diff --git a/banking_breakdown/ui.py b/banking_breakdown/ui.py
deleted file mode 100644
index cc167c2..0000000
--- a/banking_breakdown/ui.py
+++ /dev/null
@@ -1,118 +0,0 @@
-import sys
-import typing
-
-import pandas as pd
-from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, \
- QListView, QTableView
-from PyQt5 import uic, QtGui, QtCore
-import datetime
-
-
-class PandasModel(QtCore.QAbstractTableModel):
- def __init__(self, df: pd.DataFrame, parent=None):
- QtCore.QAbstractTableModel.__init__(self, parent)
- self._data = df
-
- self.horizontalHeaders = [''] * len(df.columns)
-
- for i, column in enumerate(df.columns):
- self.setHeaderData(i, QtCore.Qt.Horizontal, column)
-
- def setHeaderData(self, section, orientation, data,
- role=QtCore.Qt.EditRole):
- if orientation == QtCore.Qt.Horizontal and role in (
- QtCore.Qt.DisplayRole, QtCore.Qt.EditRole):
- try:
- self.horizontalHeaders[section] = data
- return True
- except:
- return False
- return super().setHeaderData(section, orientation, data, role)
-
- def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
- if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
- try:
- return self.horizontalHeaders[section]
- except:
- pass
- return super().headerData(section, orientation, role)
-
- def rowCount(self, parent=None):
- return len(self._data.values)
-
- def columnCount(self, parent=None):
- return self._data.columns.size
-
- def data(self, index, role=QtCore.Qt.DisplayRole):
- if index.isValid():
- if role == QtCore.Qt.DisplayRole:
- item = self._data.iloc[index.row()].iloc[index.column()]
-
- if type(item) is pd.Timestamp:
- return QtCore.QVariant(item.strftime('%Y-%m-%d'))
- else:
- return QtCore.QVariant(str(item))
- return QtCore.QVariant()
-
-
-class MainWindow(QMainWindow):
- def __init__(self, ui_file: str, categories: typing.Sequence):
- super(MainWindow, self).__init__()
- uic.loadUi(ui_file, self)
-
- self._createCategoryButton \
- = self.findChild(QPushButton, "createCategoryButton")
- self._deleteCategoryButton \
- = self.findChild(QPushButton, "deleteCategoryButton")
- self._applyCategoryButton \
- = self.findChild(QPushButton, "applyCategoryButton")
-
- self._categoryListView = self.findChild(QListView, "categoryListView")
- self._statementTableView = self.findChild(QTableView,
- "statementTableView")
-
- self._set_categories(categories)
-
- self._statementTableView.setSelectionBehavior(QTableView.SelectRows)
-
- def _set_categories(self, categories: typing.Sequence[str]):
- model = QtGui.QStandardItemModel()
- self._categoryListView.setModel(model)
-
- for category in categories:
- item = QtGui.QStandardItem(category)
- model.appendRow(item)
-
- def set_statement_data(self, df: pd.DataFrame):
- model = PandasModel(df)
- self._statementTableView.setModel(model)
-
-
-def show_main_window(ui_file, categories: typing.Sequence[str] = None,
- df: pd.DataFrame = None):
- if categories is None:
- categories = []
-
- app = QApplication(sys.argv)
- window = MainWindow(ui_file, categories)
-
- if df is not None:
- window.set_statement_data(df)
-
- window.show()
- app.exec()
-
-
-def main():
- from banking_breakdown.statement_parser import get_stripped_statement
-
- categories = ["Food", "Rent & Utilities", "Hobbies", "Education",
- "Transportation", "Social Life", "Other"]
-
- df = get_stripped_statement("../res/banking_statement_2023.csv")
-
- show_main_window("../res/main_window.ui", categories, df)
-
-
-if __name__ == "__main__":
- main()
diff --git a/banking_breakdown/ui/__init__.py b/banking_breakdown/ui/__init__.py
new file mode 100644
index 0000000..3b11f61
--- /dev/null
+++ b/banking_breakdown/ui/__init__.py
@@ -0,0 +1,37 @@
+import sys
+import typing
+
+import pandas as pd
+from PyQt6.QtWidgets import QApplication
+
+from banking_breakdown.ui.generated_wrapper import GeneratedWindowWrapper
+
+
+def show_main_window(ui_file, categories: typing.Sequence[str] = None,
+ df: pd.DataFrame = None):
+ if categories is None:
+ categories = []
+
+ app = QApplication(sys.argv)
+ window = GeneratedWindowWrapper(ui_file, categories)
+
+ if df is not None:
+ window.set_statement_data(df)
+
+ window.show()
+ app.exec()
+
+
+def main():
+ from banking_breakdown.statement_parser import get_stripped_statement
+
+ categories = ["Food", "Rent & Utilities", "Hobbies", "Education",
+ "Transportation", "Social Life", "Other"]
+
+ df = get_stripped_statement("../../res/banking_statement_2023.csv")
+
+ show_main_window("../../res/main_window.ui", categories, df)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/banking_breakdown/ui/generated.py b/banking_breakdown/ui/generated.py
new file mode 100644
index 0000000..1311a6f
--- /dev/null
+++ b/banking_breakdown/ui/generated.py
@@ -0,0 +1,74 @@
+# Form implementation generated from reading ui file 'main_window.ui'
+#
+# Created by: PyQt6 UI code generator 6.6.1
+#
+# WARNING: Any manual changes made to this file will be lost when pyuic6 is
+# run again. Do not edit this file unless you know what you are doing.
+
+
+from PyQt6 import QtCore, QtGui, QtWidgets
+
+
+class Ui_MainWindow(object):
+ def setupUi(self, MainWindow):
+ MainWindow.setObjectName("MainWindow")
+ MainWindow.resize(800, 600)
+ self.centralwidget = QtWidgets.QWidget(parent=MainWindow)
+ self.centralwidget.setObjectName("centralwidget")
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.centralwidget)
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.groupBox = QtWidgets.QGroupBox(parent=self.centralwidget)
+ self.groupBox.setObjectName("groupBox")
+ self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox)
+ self.verticalLayout_2.setObjectName("verticalLayout_2")
+ self.horizontalLayout = QtWidgets.QHBoxLayout()
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ self.createCategoryButton = QtWidgets.QPushButton(parent=self.groupBox)
+ self.createCategoryButton.setObjectName("createCategoryButton")
+ self.horizontalLayout.addWidget(self.createCategoryButton)
+ self.deleteCategoryButton = QtWidgets.QPushButton(parent=self.groupBox)
+ self.deleteCategoryButton.setObjectName("deleteCategoryButton")
+ self.horizontalLayout.addWidget(self.deleteCategoryButton)
+ self.verticalLayout_2.addLayout(self.horizontalLayout)
+ self.categoryListView = QtWidgets.QListView(parent=self.groupBox)
+ self.categoryListView.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.SizeAdjustPolicy.AdjustToContents)
+ self.categoryListView.setObjectName("categoryListView")
+ self.verticalLayout_2.addWidget(self.categoryListView)
+ self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
+ self.horizontalLayout_2.setObjectName("horizontalLayout_2")
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
+ self.horizontalLayout_2.addItem(spacerItem)
+ self.applyCategoryButton = QtWidgets.QPushButton(parent=self.groupBox)
+ self.applyCategoryButton.setObjectName("applyCategoryButton")
+ self.horizontalLayout_2.addWidget(self.applyCategoryButton)
+ self.verticalLayout_2.addLayout(self.horizontalLayout_2)
+ self.horizontalLayout_3.addWidget(self.groupBox)
+ self.groupBox_2 = QtWidgets.QGroupBox(parent=self.centralwidget)
+ self.groupBox_2.setObjectName("groupBox_2")
+ self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox_2)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.statementTableView = QtWidgets.QTableView(parent=self.groupBox_2)
+ self.statementTableView.setObjectName("statementTableView")
+ self.verticalLayout.addWidget(self.statementTableView)
+ self.horizontalLayout_3.addWidget(self.groupBox_2)
+ self.horizontalLayout_3.setStretch(1, 1)
+ MainWindow.setCentralWidget(self.centralwidget)
+ self.menubar = QtWidgets.QMenuBar(parent=MainWindow)
+ self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
+ self.menubar.setObjectName("menubar")
+ MainWindow.setMenuBar(self.menubar)
+ self.statusbar = QtWidgets.QStatusBar(parent=MainWindow)
+ self.statusbar.setObjectName("statusbar")
+ MainWindow.setStatusBar(self.statusbar)
+
+ self.retranslateUi(MainWindow)
+ QtCore.QMetaObject.connectSlotsByName(MainWindow)
+
+ def retranslateUi(self, MainWindow):
+ _translate = QtCore.QCoreApplication.translate
+ MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
+ self.groupBox.setTitle(_translate("MainWindow", "Categories"))
+ self.createCategoryButton.setText(_translate("MainWindow", "Create"))
+ self.deleteCategoryButton.setText(_translate("MainWindow", "Delete"))
+ self.applyCategoryButton.setText(_translate("MainWindow", "Apply"))
+ self.groupBox_2.setTitle(_translate("MainWindow", "Bank statement"))
diff --git a/banking_breakdown/ui/generated_wrapper.py b/banking_breakdown/ui/generated_wrapper.py
new file mode 100644
index 0000000..c19914a
--- /dev/null
+++ b/banking_breakdown/ui/generated_wrapper.py
@@ -0,0 +1,87 @@
+import typing
+
+import pandas as pd
+from PyQt6.QtWidgets import QMainWindow, QTableView
+from PyQt6 import uic, QtGui, QtCore
+from PyQt6.QtCore import Qt
+
+from banking_breakdown.ui.generated import Ui_MainWindow
+
+
+class PandasModel(QtCore.QAbstractTableModel):
+ def __init__(self, df: pd.DataFrame, parent=None):
+ QtCore.QAbstractTableModel.__init__(self, parent)
+ self._data = df
+
+ self._horizontalHeaders = [''] * len(df.columns)
+
+ for i, column in enumerate(df.columns):
+ self.setHeaderData(i, Qt.Orientation.Horizontal, column)
+
+ def setHeaderData(self, section, orientation, data,
+ role=Qt.ItemDataRole.EditRole):
+
+ if ((orientation == Qt.Orientation.Horizontal)
+ and ((role == Qt.ItemDataRole.DisplayRole)
+ or (role == Qt.ItemDataRole.EditRole))):
+
+ self._horizontalHeaders[section] = data
+ return True
+ else:
+ return super().setHeaderData(section, orientation, data, role)
+
+ def headerData(self, section, orientation,
+ role=Qt.ItemDataRole.DisplayRole):
+
+ if (orientation == Qt.Orientation.Horizontal
+ and role == Qt.ItemDataRole.DisplayRole):
+
+ return self._horizontalHeaders[section]
+ else:
+ return super().headerData(section, orientation, role)
+
+ def rowCount(self, parent=None):
+ return len(self._data.values)
+
+ def columnCount(self, parent=None):
+ return self._data.columns.size
+
+ def data(self, index, role=Qt.ItemDataRole.DisplayRole):
+ if not index.isValid():
+ return QtCore.QVariant()
+ if role != Qt.ItemDataRole.DisplayRole:
+ return QtCore.QVariant()
+
+ item = self._data.iloc[index.row()].iloc[index.column()]
+
+ if type(item) is pd.Timestamp:
+ return QtCore.QVariant(item.strftime('%Y-%m-%d'))
+ else:
+ return QtCore.QVariant(str(item))
+
+
+class GeneratedWindowWrapper(QMainWindow):
+ def __init__(self, ui_file: str, categories: typing.Sequence):
+ super(GeneratedWindowWrapper, self).__init__()
+
+ self._window = Ui_MainWindow()
+ self._window.setupUi(self)
+
+ # Set up window
+
+ self._window.statementTableView.setSelectionBehavior(
+ QTableView.SelectionBehavior.SelectRows)
+
+ self._set_categories(categories)
+
+ def _set_categories(self, categories: typing.Sequence[str]):
+ model = QtGui.QStandardItemModel()
+ self._window.categoryListView.setModel(model)
+
+ for category in categories:
+ item = QtGui.QStandardItem(category)
+ model.appendRow(item)
+
+ def set_statement_data(self, df: pd.DataFrame):
+ model = PandasModel(df)
+ self._window.statementTableView.setModel(model)
diff --git a/res/main_window.ui b/res/main_window.ui
index cd803a2..7f80b23 100644
--- a/res/main_window.ui
+++ b/res/main_window.ui
@@ -14,93 +14,82 @@
MainWindow
-
+
-
-
-
- Qt::Horizontal
+
+
+ Categories
-
-
-
- 0
- 0
-
-
-
- Categories
-
-
-
-
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Create
-
-
-
- -
-
-
- Delete
-
-
-
-
-
- -
-
-
- -
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
- Apply
-
-
-
-
-
-
-
-
-
- Bank Statement
-
-
- -
-
-
-
-
+
+ -
+
+
-
+
+
+ Create
+
+
+
+ -
+
+
+ Delete
+
+
+
+
+
+ -
+
+
+ QAbstractScrollArea::AdjustToContents
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+ Apply
+
+
+
+
+
+
+
+
+ -
+
+
+ Bank statement
+
+
+
-
+
+
+ true
+
+
+ false
+
+
+
+
@@ -114,42 +103,8 @@
23
-
-
-
-
- Save
-
-
- Ctrl+S
-
-
-
-
- Save As...
-
-
- Ctrl+Shift+S
-
-
-
-
- Open...
-
-
- Ctrl+O
-
-