import typing import qtawesome from PyQt5 import QtGui,QtCore,QtWidgets from PyQt5.QtCore import QAbstractTableModel, QModelIndex, Qt, QVariant, QSize, pyqtSignal, QPoint from PyQt5.QtWidgets import QItemDelegate, QHBoxLayout, QWidget, QTableView,QMessageBox, QComboBox from model.ProjectModel.ProjectManage import ProjectManage from utils.DBModels.ClientModels import Project from ..LoginWidgets.LoginWidget import LoginWidget from utils import Globals class QPushButton(QtWidgets.QPushButton): def __init__(self, *__args: any,clicked = None): super(QPushButton,self).__init__(*__args) self.setCursor(Qt.PointingHandCursor) self.setIconSize(QSize(25, 25)) self.editableList = [] # 表格中可编辑项 class ProjectTableModel(QAbstractTableModel): def __init__(self, header, data: list, table = None): QAbstractTableModel.__init__(self, parent=None) self.header = header self.datas = data self.checkList = ['Unchecked'] * len(self.datas) # 表格选择列表 self.editableList = [] # 表格中可编辑项 self.supportedDragActions() self.table = table def initTable(self): self.datas = [] projectDatas = ProjectManage.getAllProject() if not projectDatas: # self.layoutChanged.emit() self.table.proxy.invalidate() return for x in projectDatas: x.append('') self.datas.append(x) self.checkList = ['Unchecked'] * len(self.datas) # self.layoutChanged.emit() self.table.proxy.invalidate() def append_data(self, x): self.datas.append(x) self.checkList = ['Unchecked'] * len(self.datas) # self.layoutChanged.emit() self.table.proxy.invalidate() def insert_data(self, x, index): self.datas.insert(index, x) self.checkList = ['Unchecked'] * len(self.datas) self.table.proxy.invalidate() def remove_row(self, row): self.datas.pop(row) self.checkList = ['Unchecked'] * len(self.datas) # self.layoutChanged.emit() 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=Qt.DisplayRole): # print(Qt.__dict__.items()) if role == Qt.TextAlignmentRole: return Qt.AlignCenter if not QModelIndex.isValid(): print("行或者列有问题") return QVariant() if role == Qt.BackgroundRole: if str(self.datas[QModelIndex.row()][1]) == str(Globals.getValue('currentPro')): return QtGui.QColor('#00FF7F') return QtGui.QColor('#FFFFFF') if role == Qt.TextColorRole: if QModelIndex.column() == 6: return QtGui.QColor('#000000') return QtGui.QColor('#1A1A1A') if role == Qt.CheckStateRole: if QModelIndex.column() == 0: return Qt.Checked if self.checkList[QModelIndex.row()] == 'Checked' else Qt.Unchecked else: return None if role == Qt.ToolTipRole: if QModelIndex.column() == 0: return self.checkList[QModelIndex.row()] if role != Qt.DisplayRole: return QVariant() if role == Qt.DisplayRole or role == Qt.EditRole: if QModelIndex.row() in self.editableList: return self.datas[QModelIndex.row()][QModelIndex.column()] # print(len(self.datas), [QModelIndex.row()], [QModelIndex.column()], 'test') return QVariant(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.BackgroundRole: # return QtGui.QColor('#000000') if orientation == Qt.Horizontal: return self.header[section] def setData(self, index, value, role): row = index.row() col = index.column() if role == Qt.CheckStateRole and col == 0: self.checkList[row] = 'Checked' if value == Qt.Checked else 'Unchecked' return True if role == Qt.EditRole: self.datas[row][col] = value return True return False def flags(self, index): if index.column() == 0: return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable if index.row() in self.editableList and index.column() != 3: return Qt.ItemIsEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEditable return Qt.ItemIsEnabled def headerClick(self, isOn): self.beginResetModel() if isOn: self.checkList = [] self.checkList = ['Checked'] * len(self.datas) else: self.checkList = [] self.checkList = ['UnChecked'] * len(self.datas) self.endResetModel() 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.layoutChanged.emit() self.table.proxy.invalidate() class ProjectButtonDelegate(QItemDelegate): """该类用于向单元格中添加按钮 任务表格""" def __init__(self, parent=None): super(ProjectButtonDelegate, self).__init__(parent) def paint(self, painter, option, index): if not self.parent().indexWidget(index): button1 = QPushButton( qtawesome.icon('fa.exchange', color='#1fbb6f'), "", self.parent(), clicked=self.exchange_action ) # self.button1.setIconSize(QSize(15, 15)) # self.button1.setStyleSheet("border:none;") button2 = QPushButton( qtawesome.icon('fa.pencil', color='#4c8cf2'), "", self.parent(), clicked=self.edit_action ) button2.isEdit = True button2.oldName = False # self.button2.setStyleSheet("border:none;") button3 = QPushButton( qtawesome.icon('fa.trash', color='#ff6d6d'), "", self.parent(), clicked=self.delete_action ) # self.button3.setStyleSheet("border:none;") button1.clicked.connect(self.exchange_action) button2.clicked.connect(self.edit_action) button3.clicked.connect(self.delete_action) # self.button4.setStyleSheet("border:none;") button1.index = [index.row(), index.column()] button2.index = [index.row(), index.column()] button3.index = [index.row(), index.column()] data = self.parent().model.datas[index.row()] for x in data: if x != '': break else: button2.isEdit = False button2.setIcon(qtawesome.icon('fa.save', color='#1fbb6f')) self.parent().model.editableList.append(button2.index[0]) h_box_layout = QHBoxLayout() h_box_layout.addWidget(button1) h_box_layout.addWidget(button2) h_box_layout.addWidget(button3) h_box_layout.setContentsMargins(0, 0, 0, 0) h_box_layout.setAlignment(Qt.AlignCenter) widget = QWidget() widget.setLayout(h_box_layout) widget.setObjectName('projectBtnWidget') self.parent().setIndexWidget( index, widget ) # widget.setStyleSheet(''' # QWidget{background : #ffffff; # margin-bottom:4px; # margin-top:4px;}''') def exchange_action(self): # 切换工程按钮槽函数 sender = self.sender() projectNumber = Globals.getValue('projectNumber') if projectNumber == sender.index[0]: reply = QMessageBox.question(self.parent(), '警告', "工程已打开", QMessageBox.Yes) return print(sender.index[0]) if sender.index[0] in self.parent().model.editableList: reply = QMessageBox.question(self.parent(), '警告', "请先保存工程", QMessageBox.Yes) return self.loginWidget = LoginWidget() self.loginWidget.show() lastproType = Globals.getValue('currentProType') ProjectManage.switchProject(str(self.parent().model.datas[sender.index[0]][1]), str(self.parent().model.datas[sender.index[0]][4])) proType = Globals.getValue('currentProType') if proType in ['0', '1', '2', '3']: Globals.getValue('varTable').model.initTable() # if lastproType in ['0', '1', '2', '3']: # Globals.getValue('varTable').model.refreshComboBox() elif proType in ['4']: Globals.getValue('HartTable').model.initTable() elif proType in ['5']: Globals.getValue('TcRtdTable').model.initTable() elif proType in ['6']: Globals.getValue('AnalogTable').model.initTable() elif proType in ['8']: Globals.getValue('FFSimulateTable').model.initTable() elif proType in ['9']: Globals.getValue('HartSimulateTable').model.initTable() Globals.getValue('userTable').model.initTable() Globals.getValue('HistoryWidget').exchangeProject() Globals.setValue('projectNumber', sender.index[0]) self.parent().proxy.invalidate() def edit_action(self): sender = self.sender() model = self.parent().model cbRow = str('cb' + str(sender.index[0]) + str(4)) index = self.parent().model.index(sender.index[0], 4) delegate = self.parent().itemDelegate(index) checkbox = getattr(delegate, cbRow) if sender.isEdit: sender.setIcon(qtawesome.icon('fa.save', color='#1fbb6f')) sender.isEdit = False sender.oldName = model.datas[sender.index[0]][1] model.editableList.append(sender.index[0]) else: proMes = model.datas[sender.index[0]] name, des, proType = str(proMes[1]), str(proMes[2]), str(proMes[4]) if not name or not proType: reply = QMessageBox.question(self.parent(), '警告', "有字段为空", QMessageBox.Yes) return if sender.oldName: if ProjectManage.editProject(name = sender.oldName, Nname = name, des = des): reply = QMessageBox.question(self.parent(), '警告', "工程名相同", QMessageBox.Yes) return else: if ProjectManage.createProject(name = name, proType = proType, des= des): reply = QMessageBox.question(self.parent(), '警告', "工程名相同", QMessageBox.Yes) return sender.setIcon(qtawesome.icon('fa.pencil', color='#4c8cf2')) checkbox.setEnabled(False) sender.isEdit = True model.editableList.remove(sender.index[0]) rowIndex = sender.index[0] proMes = ProjectManage.getByName(name) proMes.append('') model.insert_data(proMes, rowIndex) model.remove_row(rowIndex + 1) def delete_action(self): sender = self.sender() model = self.parent().model name = str(model.datas[sender.index[0]][1]) ProjectManage.deleteProject(name = name) model.remove_row(sender.index[0]) class ProTypeBoxDelegate(ProjectButtonDelegate): def __init__(self, parent=None): super(ProTypeBoxDelegate, self).__init__(parent) def paint(self, painter, option, index): if not self.parent().indexWidget(index): data = self.parent().model.datas[index.row()] comboBox = str('cb' + str(index.row()) + str(index.column())) setattr(self, comboBox, QComboBox(self.parent())) cmBox = getattr(self, comboBox) item = ['MODBUSTCP 主站模式', 'MODBUSTCP 从站模式', 'MODBUSRTU 主站模式', 'MODBUSRTU 从站模式'] cmBox.addItems(item) cmBox.index = [index.row(), index.column()] if self.parent().model.datas[index.row()][index.column()] in range(10): cmBox.setCurrentIndex(self.parent().model.datas[index.row()][index.column()]) else: cmBox.setCurrentIndex(-1) # self.parent().model.cmBoxList.append(cmBox) cmBox.currentIndexChanged.connect(self.indexChange) cmBox.setObjectName('ProTypeBox') cmBox.setEditable(True) cmBox.lineEdit().setAlignment(Qt.AlignCenter) if str(data[index.column()]): #button2.isEdit = False cmBox.setEnabled(False) #self.parent().model.editableList.append(button2.index[0]) else: #button2.isEdit = True cmBox.setEnabled(True) h_box_layout = QHBoxLayout() h_box_layout.addWidget(cmBox) h_box_layout.setContentsMargins(0, 0, 0, 0) h_box_layout.setAlignment(Qt.AlignCenter) cmBox.index = [index.row(), index.column()] widget = QWidget() widget.setLayout(h_box_layout) self.parent().setIndexWidget( index, widget ) def indexChange(self): sender = self.sender() index = sender.currentIndex() text = sender.itemText(index) self.parent().model.datas[sender.index[0]][sender.index[1]] = index class BackgroundDelegate(QtWidgets.QStyledItemDelegate): def __init__(self, *args): super(BackgroundDelegate, self).__init__(*args) self.setObjectName('item') def paint(self, painter, option, index): if index.data(QtCore.Qt.BackgroundRole): height = option.rect.height() top = option.rect.top() option.rect.setHeight(height - 7) option.rect.moveTop(top + 6) painter.fillRect(option.rect, index.data(QtCore.Qt.BackgroundRole)) super().paint(painter, option, index)