123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- from view.gui.custom_widgets import QTableWidgetPandasDFDeletable
- from PyQt5.QtWidgets import QAbstractItemView, QHeaderView, QLineEdit, QWidget
- from PyQt5.QtCore import pyqtSlot, QObject, pyqtSignal
- import pandas as pd
- from view.python_core.utils.deduplicator import dedupilicate
- from collections import OrderedDict
- import copy
- class DataManager(QObject):
- remove_data_signal = pyqtSignal(str, name="remove data signal")
- def __init__(self, parent: QWidget, flag_values_to_use: dict,
- p1_values_to_use: dict, label_joiner: str,
- default_label_cols: list, precedence_order: list):
- """
- The columns for gui-table are composed as follows: The column for the user-editable data label, followed by
- those defined in <p1_values_to_use>, followed by those defined in <flag_values_to_use>.
- The internal Dataframe variable <df> consists of the same columns, except the column for data labels. The row
- indices of <df> are internally generated labels.
- :param flag_values_to_use: dict, containing info about the flags values to store with data.
- Values are flag names and keys are the column names under which they will be shown
- :param p1_values_to_use: dict, containing info about the p1 values to store with data.
- Values are functions that take one argument, p1, as input and returns the string to show. Keys are the column
- names under which they will be shown
- :param label_joiner: str, which is used to join metadata values to form labels. E.g.: _ and -
- :param default_label_cols: list, list of column names whose values are to be joined to form the default label
- :param list precedence_order: these column names will be placed before others, if they are used
- """
- super().__init__()
- self.label_line_edits = {}
- self.label_col_name = "gui_label"
- self.label_joiner = label_joiner
- self.defaultLabelCols = default_label_cols
- self.ui_table = None
- self.flag_values_to_use = flag_values_to_use
- self.p1_values_to_use = p1_values_to_use
- column_headers = \
- [self.label_col_name] + \
- self.reorder_column_names(
- list(self.flag_values_to_use.keys()) + list(self.p1_values_to_use.keys()), precedence_order)
- self.init_ui(parent, column_headers)
- self.df = pd.DataFrame(columns=column_headers[1:])
- def reorder_column_names(self, column_names: list, precedence_order: list):
- precedence_order2retain = [x for x in precedence_order if x in column_names]
- other_col_names = [x for x in column_names if x not in precedence_order]
- return precedence_order2retain + other_col_names
- def init_ui(self, parent, horizontal_headers=()):
- self.ui_table = QTableWidgetPandasDFDeletable(parent=parent)
- self.ui_table.setColumnCount(len(horizontal_headers))
- self.ui_table.setHorizontalHeaderLabels(horizontal_headers)
- self.ui_table.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
- self.ui_table.setSelectionBehavior(QAbstractItemView.SelectRows)
- self.ui_table.setSelectionMode(QAbstractItemView.SingleSelection)
- self.ui_table.remove_data_signal.connect(self.row_deleted)
- def get_item_at(self, row_ind, col_ind):
- if col_ind == 1:
- return self.ui_table.cellWidget(row_ind, col_ind).text()
- else:
- return self.ui_table.item(row_ind, col_ind).text()
- def add_data(self, flags, p1, label_suggestion):
- row = pd.Series()
- for k, v in self.p1_values_to_use.items():
- row[k] = str(v(p1))
- for k, v in self.flag_values_to_use.items():
- row[k] = str(flags[v])
- label = dedupilicate(value=label_suggestion, existing_values=self.get_all_internal_labels())
- self.ui_table.add_row(row)
- row.name = label
- self.df = self.df.append(row)
- le = QLineEdit(label)
- self.ui_table.setCellWidget(self.ui_table.rowCount() - 1, 0, le)
- self.label_line_edits[label] = le
- self.ui_table.selectRow(self.ui_table.rowCount() - 1)
- return label
- def get_selected_data_label(self):
- return self.df.index.values[self.ui_table.selectionModel().selectedRows()[0].row()]
- def get_all_internal_labels(self):
- return self.df.index.values.tolist()
- @pyqtSlot(int, name="row deleted")
- def row_deleted(self, row_ind):
- label_of_data_to_delete = self.df.index.values[row_ind]
- del self.label_line_edits[label_of_data_to_delete]
- self.df.drop(index=label_of_data_to_delete, inplace=True)
- self.remove_data_signal.emit(label_of_data_to_delete)
|