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.

372 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
7 months ago
from model.ProjectModel.ProjectManage import ProjectManage
from ..LoginWidgets.LoginWidget import LoginWidget
from utils import Globals
7 months ago
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]))
if not Globals.getValue('switchState'):
pass
else:
Globals.getValue('MainWindows').delecteWidget()
Globals.getValue('MainWindows').createWidgets()
7 months ago
modelLists = ['ModbusTcpMasterTable', 'ModbusTcpSlaveTable', 'ModbusRtuMasterTable', \
'ModbusRtuSlaveTable', 'HartTable', 'TcRtdTable', 'AnalogTable', 'HartSimulateTable', 'userTable']
7 months ago
for l in modelLists:
# print(l)
7 months ago
Globals.getValue(l).model.initTable()
3 months ago
QtWidgets.QApplication.processEvents()
5 months ago
Globals.clearValue('forceVars')#清除颜色
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
Globals.setValue('switchState', True)#用来判断是否是第一次切换
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)