You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

358 lines
14 KiB
Python

7 months ago
import typing
import qtawesome
from PyQt5 import QtGui,QtCore,QtWidgets
from PyQt5.QtCore import QAbstractTableModel, QModelIndex, Qt, QVariant, QSize
from PyQt5.QtWidgets import QItemDelegate, QHBoxLayout, QWidget,QMessageBox, QComboBox
from model.ProjectModel.ProjectManage import ProjectManage
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.table.proxy.invalidate()
return
for x in projectDatas:
x.append('')
self.datas.append(x)
self.checkList = ['Unchecked'] * len(self.datas)
self.table.proxy.invalidate()
def append_data(self, x):
self.datas.append(x)
self.checkList = ['Unchecked'] * len(self.datas)
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.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):
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')
7 months ago
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()]
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 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.table.proxy.invalidate()
class ProjectButtonDelegate(QItemDelegate):
"""该类用于向单元格中添加按钮 任务表格"""
def __init__(self, parent=None):
super(ProjectButtonDelegate, self).__init__(parent)
def sizeHint(self, option, index):
"""设置项目的尺寸提示,确保足够的高度"""
size = super().sizeHint(option, index)
size.setHeight(max(60, size.height())) # 最小高度60px
return size
7 months ago
def paint(self, painter, option, index):
# 首先绘制背景颜色与BackgroundDelegate保持一致
if index.data(QtCore.Qt.BackgroundRole):
height = option.rect.height()
top = option.rect.top()
# 减少高度调整,保持更多的绘制区域
paint_rect = option.rect
paint_rect.setHeight(max(56, height - 4)) # 最小保持56px高度
paint_rect.moveTop(top + 2)
painter.fillRect(paint_rect, index.data(QtCore.Qt.BackgroundRole))
# 然后创建按钮部件
7 months ago
if not self.parent().indexWidget(index):
button1 = QPushButton(
qtawesome.icon('fa.exchange', color='#1fbb6f'),
"",
self.parent(),
clicked=self.exchange_action
)
button2 = QPushButton(
qtawesome.icon('fa.pencil', color='#4c8cf2'),
"",
self.parent(),
clicked=self.edit_action
)
button2.isEdit = True
button2.oldName = False
button3 = QPushButton(
qtawesome.icon('fa.trash', color='#ff6d6d'),
"",
self.parent(),
clicked=self.delete_action
)
button1.clicked.connect(self.exchange_action)
button2.clicked.connect(self.edit_action)
button3.clicked.connect(self.delete_action)
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')
# 设置widget的背景为透明让底层的背景颜色显示出来
widget.setStyleSheet("""
QWidget#projectBtnWidget {
background-color: transparent;
}
""")
7 months ago
self.parent().setIndexWidget(
index,
widget
)
def exchange_action(self):
# 切换工程按钮槽函数
sender = self.sender()
projectName = Globals.getValue('currentPro')
if projectName == str(self.parent().model.datas[sender.index[0]][1]):
reply = QMessageBox.question(self.parent(),
'警告',
"工程已打开",
QMessageBox.Yes)
return
if sender.index[0] in self.parent().model.editableList:
reply = QMessageBox.question(self.parent(),
'警告',
"请先保存工程",
QMessageBox.Yes)
return
3 months ago
# 初始化读取数据库数据,添加进度条
progress = QtWidgets.QProgressDialog()
progress.setWindowTitle("提示")
3 months ago
progress.setLabelText("正在加载工程数据...")
progress.setCancelButton(None)
progress.setMinimum(0)
progress.setMaximum(0)
progress.setWindowModality(QtCore.Qt.ApplicationModal)
progress.setMinimumDuration(0)
progress.show()
QtWidgets.QApplication.processEvents()
ProjectManage.switchProject(str(self.parent().model.datas[sender.index[0]][1]))
7 months ago
modelLists = ['ModbusTcpMasterTable', 'ModbusTcpSlaveTable', 'ModbusRtuMasterTable', \
'ModbusRtuSlaveTable', 'HartTable', 'TcRtdTable', 'AnalogTable', 'HartSimulateTable', 'userTable']
7 months ago
for l in modelLists:
Globals.getValue(l).model.initTable()
3 months ago
QtWidgets.QApplication.processEvents()
5 months ago
profibusTabWidgets = ['DP主站', 'DP从站', 'PA主站', 'PA从站']
for widget in profibusTabWidgets:
3 months ago
Globals.getValue(widget).switchProject()
QtWidgets.QApplication.processEvents()
7 months ago
3 months ago
progress.close()
QtWidgets.QApplication.processEvents()
7 months ago
self.parent().proxy.invalidate()
3 months ago
self.loginWidget = LoginWidget()
self.loginWidget.show()
7 months ago
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, = str(proMes[1]), str(proMes[2])
if not name :
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, 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)
self.parent().proxy.invalidate()
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])
if name == Globals.getValue('currentPro'):
Globals.setValue('currentPro', None)
class BackgroundDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, *args):
super(BackgroundDelegate, self).__init__(*args)
self.setObjectName('item')
def sizeHint(self, option, index):
"""设置项目的尺寸提示,确保足够的高度"""
size = super().sizeHint(option, index)
size.setHeight(max(60, size.height())) # 最小高度60px
return size
7 months ago
def paint(self, painter, option, index):
# 确保绘制区域有足够的高度
7 months ago
if index.data(QtCore.Qt.BackgroundRole):
height = option.rect.height()
top = option.rect.top()
# 减少高度调整,保持更多的绘制区域
option.rect.setHeight(max(56, height - 4)) # 最小保持56px高度
option.rect.moveTop(top + 2)
7 months ago
painter.fillRect(option.rect, index.data(QtCore.Qt.BackgroundRole))
super().paint(painter, option, index)