# from PyQt5.QtWidgets import QTableView, QHeaderView, QAbstractItemView # from PyQt5.QtCore import Qt, QModelIndex from PySide6.QtWidgets import QTableView, QHeaderView, QAbstractItemView from PySide6.QtCore import Qt, QModelIndex STRETCH = QHeaderView.Stretch class TableView(QTableView): def __init__(self, name, model, col_sizes=[], method_selected_row=None, editable=False): super(TableView, self).__init__() self.setObjectName(name) self.verticalHeader().hide() self.setGridStyle(Qt.DotLine) self.setAlternatingRowColors(True) if not editable: self.setEditTriggers(QAbstractItemView.NoEditTriggers) self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setSelectionMode(QAbstractItemView.SingleSelection) self.setVerticalScrollMode(QAbstractItemView.ScrollPerItem) self.model = model self.method_selected_row = method_selected_row self.doubleClicked.connect(self.on_selected_row) self.clicked.connect(self.selected_clicked) self.setWordWrap(False) self.selected_rows = [] self.selected_row_clicked = None if model: self.setModel(model) header = self.horizontalHeader() header.setStretchLastSection(True) if col_sizes: for i, size in enumerate(col_sizes): if isinstance(size, int): header.resizeSection(i, size) else: header.setSectionResizeMode(i, STRETCH) def is_active_selection(self): value = self.selectionMode() if value == QAbstractItemView.MultiSelection: return True return False def active_selection(self, multi): if multi: self.setSelectionBehavior(QAbstractItemView.SelectRows) self.setSelectionMode(QAbstractItemView.MultiSelection) else: self.setSelectionMode(QAbstractItemView.SingleSelection) def clear_selected(self): self.clearSelection() self.selected_rows = [] self.selected_row_clicked = None def get_selected_rows(self): rows = [] for row_index in self.selected_rows: rows.append(self.model.get_data(row_index)) return rows def get_selected_clicked(self): return self.model.get_data(self.selected_row_clicked) def selected_clicked(self): selected_idx = self.currentIndex() self.selected_rows.append(selected_idx) self.selected_row_clicked = selected_idx def on_selected_row(self): selected_idx = self.currentIndex() if selected_idx: data_row = self.model.get_data(selected_idx) if data_row and self.method_selected_row: self.method_selected_row(data_row) def rowsInserted(self, index, start, end): # Adjust scroll to last row (bottom) self.selectRow(end) selected_idx = self.currentIndex() if selected_idx: self.selected_row_clicked = selected_idx self.scrollToBottom() def removeElement(self, index, ignore_focus=False): if not index: return if index.row() >= 0: if self.hasFocus() or ignore_focus: self.model.removeId(index.row(), index) # This options is unnecessary deleteRecords function not implemented # id_ = self.model.removeId(index.row(), index) # self.model.deleteRecords([id_]) self.model.layoutChanged.emit() def delete_selected(self): # order rows by index reverse for delete correct records rows_ = {r.row(): r for r in self.selected_rows} rows_ = dict(sorted(rows_.items(), key=lambda x: x[0], reverse=True)) for idx in rows_.values(): self.removeElement(idx, True) def delete_item(self, ignore_focus=False): item_removed = {} selected_idx = self.currentIndex() item_removed = self.model.get_data(selected_idx) self.removeElement(selected_idx, ignore_focus) return item_removed def moved_selection(self, key): selected_idx = self.currentIndex() if key == Qt.Key_Down: self.selectRow(selected_idx.row() + 1) elif key == Qt.Key_Up: self.selectRow(selected_idx.row() - 1) def clearData(self): index = self.currentIndex() self.model.removeRows(0, len(self.model._data), index) self._data = [] self.model.layoutChanged.emit()