banking-breakdown/banking_breakdown/ui/custom_ui_items.py

162 lines
5.3 KiB
Python

import pandas as pd
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QPixmap, QAction
from PyQt6.QtWidgets import QHBoxLayout, QLabel, QMenu, QInputDialog, \
QMessageBox
from banking_breakdown.ui.pandas_model import PandasModel
class WarningItem(QHBoxLayout):
"""Item appearing at top of Window with warning icon."""
def __init__(self, text: str, parent=None):
super(WarningItem, self).__init__()
self._warningIcon = QLabel()
pixmap = QPixmap("res/warning.png")
self._warningIcon.setPixmap(pixmap)
self._label = QLabel(text)
self._label.setWordWrap(True)
self.addWidget(self._warningIcon)
self.addWidget(self._label)
self.setStretch(0, 0)
self.setStretch(1, 1)
def hide(self):
self._label.hide()
self._warningIcon.hide()
class HeaderContextMenu(QMenu):
"""Context menu appearing when right-clicking the header of the QTableView.
"""
def __init__(self, column_index, pandas_model: PandasModel, callback=None,
parent=None):
super(HeaderContextMenu, self).__init__()
self._pandas_model = pandas_model
self._callback = callback
self._column_index = column_index
self._column_text \
= self._pandas_model.headerData(self._column_index,
Qt.Orientation.Horizontal)
# Define assign action
assign_menu = QMenu("Assign type", self)
assign_date_action = QAction("date", self)
assign_float_action = QAction("float", self)
assign_menu.addAction(assign_date_action)
assign_menu.addAction(assign_float_action)
assign_date_action.triggered.connect(self._assign_date_handler)
assign_float_action.triggered.connect(self._assign_float_handler)
# Define other actions
rename_action = QAction("Rename", self)
delete_action = QAction("Delete", self)
switch_action = QAction("Switch position", self)
rename_action.triggered.connect(self._rename_handler)
delete_action.triggered.connect(self._delete_handler)
switch_action.triggered.connect(self._switch_handler)
# Add actions to menu
self.addAction(rename_action)
self.addAction(delete_action)
self.addAction(switch_action)
self.addAction(assign_menu.menuAction())
def _rename_handler(self):
new_name, flag = QInputDialog.getText(self, "Rename column",
"New name:",
text=self._column_text)
if not flag:
return
if (new_name != self._column_text) and (new_name != ''):
try:
self._pandas_model.rename_column(self._column_text, new_name)
except:
QMessageBox.warning(self, "No action performed",
"An error occurred.")
if self._callback:
self._callback()
def _delete_handler(self):
button = QMessageBox.question(self, "Delete column",
f"Are you sure you want to delete"
f" column '{self._column_text}'?")
if button == QMessageBox.StandardButton.Yes:
self._pandas_model.delete_column_by_index(self._column_index)
if self._callback:
self._callback()
def _switch_handler(self):
df = self._pandas_model.get_dataframe()
columns = [column for column in df.columns
if column != self._column_text]
other_name, flag = QInputDialog.getItem(self, "Switch column position",
f"Switch position of colum "
f"'{self._column_text}' with:",
columns, editable=False)
if not flag:
return
self._pandas_model.switch_columns(self._column_text, other_name)
if self._callback:
self._callback()
def _assign_date_handler(self):
date_format, flag = QInputDialog.getText(self, "Format",
"Format:",
text="%d.%m.%Y")
if not flag:
return
try:
self._pandas_model.assign_date_column(self._column_text,
date_format)
except:
QMessageBox.warning(self, "No action performed",
"An error occurred.")
if self._callback:
self._callback()
def _assign_float_handler(self):
chars = ['.', ',']
decimal_sep, flag = QInputDialog.getItem(self, "Decimal separator",
"Decimal separator:",
chars, editable=False)
if not flag:
return
try:
self._pandas_model.assign_float_column(self._column_text,
decimal_sep)
except:
QMessageBox.warning(self, "No action performed",
"An error occurred.")
if self._callback:
self._callback()