diff options
Diffstat (limited to 'src/main/python/utils/streamTable.py')
-rw-r--r-- | src/main/python/utils/streamTable.py | 104 |
1 files changed, 80 insertions, 24 deletions
diff --git a/src/main/python/utils/streamTable.py b/src/main/python/utils/streamTable.py index acccdee..8b3b220 100644 --- a/src/main/python/utils/streamTable.py +++ b/src/main/python/utils/streamTable.py @@ -5,13 +5,17 @@ from PyQt5.QtWidgets import QTableView, QMenu, QGraphicsRectItem, QInputDialog, from collections import defaultdict class streamTableModel(QAbstractTableModel): + """ + Defines the table model for the table view + """ updateEvent = pyqtSignal() def __init__(self, parent, list, header, *args): super(streamTableModel, self).__init__(parent, *args) self.list = list self.header = header - + + # column count, row count, data and setdata are important methods to be overloaded def columnCount(self, parent=None): return len(self.list) @@ -19,85 +23,108 @@ class streamTableModel(QAbstractTableModel): return len(self.header) def data(self, index, role): + # retunrs data at index if role == Qt.TextAlignmentRole: return Qt.AlignHCenter + if role == Qt.BackgroundColorRole: return Qt.white + if not index.isValid(): return None + elif role != Qt.DisplayRole: return None + if index.row() == 0: - return self.list[index.column()].toPlainText() + return self.list[index.column()].toPlainText() # return label name else: - return self.list[index.column()].values[self.header[index.row()]] + return self.list[index.column()].values[self.header[index.row()]] # retunr label values def setData(self, index, value, role): + # defines how to manipulate data at a given index with value returns sucess value if not index.isValid(): return False + elif role != Qt.EditRole: return False + if index.row() == 0: - self.list[index.column()].setPlainText(value) + self.list[index.column()].setPlainText(value) # change label text else: - self.list[index.column()].values[self.header[index.row()]] = value + self.list[index.column()].values[self.header[index.row()]] = value #change label values + return True def insertColumn(self, int=None, item=None): + # inserting a label item int = int if int else self.rowCount()+1 self.beginInsertColumns(QModelIndex(), int, int) self.list.insert(int, item) + item.nameChanged.connect(self.parent().repaint) self.endInsertColumns() self.updateEvent.emit() def insertRow(self, int=None, name="newVal"): + # inserting a header property self.beginInsertRows(QModelIndex(), int, int) self.header.insert(int, name) self.endInsertRows() self.updateEvent.emit() def deleteRow(self, row): + # removing a property self.beginRemoveRows(QModelIndex(), row, row) - valName = self.header.pop(row) + valName = self.header.pop(row) # remove from header self.endRemoveRows() + for i in self.list: - i.values.pop(valName) - self.updateEvent.emit() + i.values.pop(valName) #clear dictionary + + self.updateEvent.emit() # update request def headerData(self, col, orientation, role): + # definds how to fetch header data if orientation == Qt.Vertical and role == Qt.DisplayRole: return self.header[col] return None def flags(self, index): + # defines item editable flag return (super(streamTableModel, self).flags(index) | Qt.ItemIsEditable) class streamTable(QTableView): - + """ + subclasses stream table to display data properly + """ def __init__(self, itemLabels=[], canvas=None, parent=None): super(streamTable, self).__init__(parent=parent) self.canvas = canvas + for i in itemLabels: - i.nameChanged.connect(self.repaint) - header = ["name", "val1", "val2", "val3", "val4", "val5"] + i.nameChanged.connect(self.repaint) # connect repaint requests on name change + + header = ["name", "val1", "val2", "val3", "val4", "val5"] # prepare header names self.model = streamTableModel(self, itemLabels, header) - self.setShowGrid(False) + self.setShowGrid(False) # disable table grid + + self.horizontalHeader().hide() # remove horizontal header - self.horizontalHeader().hide() - header = verticalHeader(Qt.Vertical, self) + header = verticalHeader(Qt.Vertical, self) #create custom vertical header self.setVerticalHeader(header) header.labelChangeRequested.connect(self.labelChange) - self.setModel(self.model) - self.borderThickness = defaultdict(lambda: False) + self.setModel(self.model) #declare model + self.borderThickness = defaultdict(lambda: False) #thickness bool dict self.model.updateEvent.connect(self.resizeHandler) self.setItemDelegateForRow(0, drawBorderDelegate(self)) + self.borderThickness[0] = True # set border true for name row def mousePressEvent(self, event): + # handle context menu request if event.button() == Qt.RightButton: point = event.pos() - # col = self.getCol(point.x()) index = self.indexAt(point) menu = QMenu("Context Menu", self) menu.addAction("Toggle bottom border thickness", lambda x=index.row(): self.changeRowBorder(x)) @@ -108,14 +135,17 @@ class streamTable(QTableView): return super(streamTable, self).mousePressEvent(event) def changeRowBorder(self, row): + # toggle column border thicnkess if self.borderThickness[row]: - self.borderThickness[row] = False + self.borderThickness.pop(row) self.setItemDelegateForRow(row, QStyledItemDelegate(self)) else: self.borderThickness[row] = True self.setItemDelegateForRow(row, drawBorderDelegate(self)) + self.verticalHeader().repaint() def labelChange(self, index): + # label name change newName, bool = QInputDialog.getText(self, "Change Property Name", "Enter new name", text = self.model.header[index]) if bool: @@ -125,6 +155,7 @@ class streamTable(QTableView): self.repaint() def insertRowBottom(self, row): + # dialog box for new property name, bool = QInputDialog.getText(self, "New Property", "Enter name", text = "newVal") if bool: @@ -145,12 +176,23 @@ class streamTable(QTableView): for i in range(self.model.rowCount()): h += self.rowHeight(i) return QRect(0, 0, w, h) + + def __getstate__(self): + return { + "borderThickness": self.borderThickness, + "header": self.model.header + } + + def __setstate__(self, dict): + for key, value in dict['borderThickness'].items(): + self.borderThickness[key] = value + self.model.header = dict['header'] + self.repaint() class drawBorderDelegate(QStyledItemDelegate): - - # def __init__(self, parent): - # super(drawBorderDelegate, self).__init__(parent) - + """ + class for drawing border line + """ def paint(self, painter, option, index): rect = option.rect painter.drawLine(rect.bottomLeft(), rect.bottomRight()) @@ -158,7 +200,9 @@ class drawBorderDelegate(QStyledItemDelegate): super(drawBorderDelegate, self).paint(painter, option, index) class moveRect(QGraphicsRectItem): - + """ + use to move the table on the scene + """ def __init__(self, sideLength = 15, *args): super(moveRect, self).__init__(-sideLength, -sideLength, sideLength, sideLength) self.setBrush(Qt.transparent) @@ -175,9 +219,21 @@ class moveRect(QGraphicsRectItem): return super(moveRect, self).hoverLeaveEvent(event) class verticalHeader(QHeaderView): + """ + Custom Vertical header for the table, with line border against corresponding rows + """ labelChangeRequested = pyqtSignal(int) def mouseDoubleClickEvent(self, event): index = self.logicalIndexAt(event.pos()) self.labelChangeRequested.emit(index) - return super().mouseDoubleClickEvent(event)
\ No newline at end of file + return super().mouseDoubleClickEvent(event) + + def paintSection(self, painter, option, index): + painter.save() + super(verticalHeader, self).paintSection(painter, option, index) + painter.restore() + if self.parentWidget().borderThickness[index]: + rect = option + painter.drawLine(rect.bottomLeft(), rect.bottomRight()) + painter.setPen(QPen(Qt.black, 1, Qt.SolidLine))
\ No newline at end of file |