import typing import re # from matplotlib.pyplot import box import qtawesome from PyQt5 import QtGui,QtCore,QtWidgets from PyQt5.QtCore import QAbstractTableModel, QModelIndex, Qt, QVariant, QSize from PyQt5.QtWidgets import QItemDelegate, QHBoxLayout, QWidget, QPushButton, QMessageBox, QLineEdit, QComboBox, QStyledItemDelegate from UI.LoadingDataWidget import LoadingDataWidget class VarTableModel(QAbstractTableModel): ''' 变量表模型类''' def __init__(self, header, data: list, table = None): ''' header : 表头变量 data : 表格内容 table : 缺省参数 ''' QAbstractTableModel.__init__(self, parent=None) self.header = header self.datas = data self.checkList = ['Unchecked'] * len(self.datas) self.supportedDragActions() self.table = table self.editableList = [] # 表格中可编辑项 def append_data(self, x): self.datas.append(x) self.checkList = ['Unchecked'] * len(self.datas) self.table.proxy.invalidate() # self.layoutChanged.emit() def insert_data(self, x, index): self.datas.insert(index, x) self.checkList = ['Unchecked'] * len(self.datas) self.table.proxy.invalidate() def updateColumn(self, column, value): if column < 0 or column >= self.columnCount(): print("列索引超出范围") return for row in range(self.rowCount()): self.datas[row][column] = value self.table.proxy.invalidate() # self.layoutChanged.emit() # 通知视图数据已更改 # self.dataChanged.emit() def remove_row(self, row): self.datas.pop(row) self.checkList = ['UnChecked'] * len(self.datas) self.table.proxy.invalidate() def rowCount(self, parent: QModelIndex = ...) -> int: if len(self.datas) > 0: return len(self.datas) return 0 def columnCount(self, parent: QModelIndex = ...) -> int: return len(self.header) def data(self, QModelIndex, role=None): # print(Qt.__dict__.items()) if role == Qt.TextAlignmentRole: return Qt.AlignCenter if not QModelIndex.isValid(): print("行或者列有问题") return QVariant() if role == Qt.TextColorRole: return QtGui.QColor('#1A1A1A') if role == Qt.DisplayRole or role == Qt.EditRole: if QModelIndex.row() in self.editableList or 'w' in self.datas[QModelIndex.row()][4]: return self.datas[QModelIndex.row()][QModelIndex.column()] if role != Qt.DisplayRole: return QVariant() return self.datas[QModelIndex.row()][QModelIndex.column()] def headerData(self, section: int, orientation: Qt.Orientation, role: int = ...) -> typing.Any: # 表头 if role != Qt.DisplayRole: return None if role == Qt.SizeHintRole: # print(self.datas[QModelIndex.row()][QModelIndex.column()].find('\r\n')) return QSize(500, 500) if orientation == Qt.Horizontal: return self.header[section] # if orientation == Qt.Vertical: # return str(section + 1) def setData(self, index, value, role): row = index.row() col = index.column() if role == Qt.EditRole: self.datas[row][col] = value return True return True def flags(self, index): # if index.column() == 0: # return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable if index.row() in self.editableList and index.column() or index.column() == 6: return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEditable if 'w' in self.datas[index.row()][4] and index.column() == 5: return Qt.ItemIsEnabled | Qt.ItemIsEditable return Qt.ItemIsEnabled def dragMoveEvent(self, event): event.setDropAction(QtCore.Qt.MoveAction) event.accept() def moveRow(self, sourceParent: QModelIndex, sourceRow: int, destinationParent: QModelIndex, destinationChild: int) -> bool: if self.datas[destinationChild] == self.datas[sourceRow]: return self.datas[sourceRow], self.datas[destinationChild] = self.datas[destinationChild], self.datas[sourceRow] self.table.proxy.invalidate() class VarButtonDelegate(QItemDelegate): """该类用于向单元格中添加按钮 任务表格""" def __init__(self, parent=None): super(VarButtonDelegate, self).__init__(parent) def paint(self, painter, option, index): if not self.parent().indexWidget(index): startActionBtn = QPushButton( qtawesome.icon('fa.play', color='#1fbb6f'), "", self.parent() ) if 'w' not in self.parent().model.datas[index.row()][4]: return startActionBtn.index = [index.row(), index.column()] startActionBtn.setToolTip('强制') refreshButton = QPushButton( qtawesome.icon('mdi6.refresh', color='#1fbb6f'), "", self.parent() ) refreshButton.setToolTip('刷新') refreshButton.clicked.connect(self.refreshData) parameEditline = QLineEdit() parameEditline.setObjectName('parameEditline') boxLayout = QHBoxLayout() boxLayout.addWidget(parameEditline) boxLayout.addWidget(startActionBtn) boxLayout.addWidget(refreshButton) startActionBtn.clicked.connect(lambda: self.startAction(parameEditline)) startActionBtn.setObjectName('startActionBtn') boxLayout.setContentsMargins(2, 0, 0, 2) boxLayout.setAlignment(Qt.AlignCenter) widget = QWidget() widget.setLayout(boxLayout) self.parent().setIndexWidget( index, widget ) def startAction(self, parameEditline): sender = self.sender() model = self.parent().model # value = model.datas[sender.index[0]][sender.index[1]] value = parameEditline.text() pattern = re.compile(r'[^0-9\.-]+') if not value or re.findall(pattern, str(value)): reply = QMessageBox.question(self.parent(), '警告', "请输入强制值或数字", QMessageBox.Yes) return def refreshData(self): self.loadingDataWidget = LoadingDataWidget() self.loadingDataWidget.loadData() class ComboBoxDelegate(QStyledItemDelegate): def __init__(self, parent=None): super(ComboBoxDelegate, self).__init__(parent) def createEditor(self, parent, option, index): # 仅在第二列第二行创建编辑器 if index.row() == 5 and index.column() == 5: comboBox = QComboBox(parent) comboBox.addItems(["非服务", "手动初始化", "本地超驰", '手动', '自动', '级联', '远程级联', '远程输出']) return comboBox else: return super().createEditor(parent, option, index) def setEditorData(self, editor, index): if index.row() == 5 and index.column() == 5: # value = index.model().data(index, Qt.EditRole) value = "非服务" if value: editor.setCurrentText(value) else: super().setEditorData(editor, index) def setModelData(self, editor, model, index): if index.row() == 5 and index.column() == 5: model.setData(index, editor.currentText(), Qt.EditRole) else: super().setModelData(editor, model, index) def updateEditorGeometry(self, editor, option, index): editor.setGeometry(option.rect) class refreshButtonDelegate(QItemDelegate): """该类用于向单元格中添加按钮 任务表格""" def __init__(self, parent=None): super(refreshButtonDelegate, self).__init__(parent) def paint(self, painter, option, index): if not self.parent().indexWidget(index): startActionBtn = QPushButton( qtawesome.icon('mdi6.refresh', color='#1fbb6f'), "", self.parent() ) if 'w' not in self.parent().model.datas[index.row()][4]: return startActionBtn.index = [index.row(), index.column()] parameEditline = QLineEdit() parameEditline.setObjectName('parameEditline') boxLayout = QHBoxLayout() boxLayout.addWidget(parameEditline) boxLayout.addWidget(startActionBtn) startActionBtn.clicked.connect(lambda: self.startAction(parameEditline)) startActionBtn.setObjectName('startActionBtn') boxLayout.setContentsMargins(2, 0, 0, 2) boxLayout.setAlignment(Qt.AlignCenter) widget = QWidget() widget.setLayout(boxLayout) self.parent().setIndexWidget( index, widget )