|
|
|
@ -182,34 +182,43 @@ class VarTableModel(QAbstractTableModel):
|
|
|
|
|
#功能类型的index是5,通讯类型index是10
|
|
|
|
|
|
|
|
|
|
for i in range(len(self.datas)):
|
|
|
|
|
cbRow = str('cb' + str(i) + str(comboBoxColumn))
|
|
|
|
|
index = self.index(i, int(comboBoxColumn))
|
|
|
|
|
delegate = self.table.itemDelegate(index)
|
|
|
|
|
|
|
|
|
|
# 方法1:尝试通过indexWidget获取已存在的comboBox
|
|
|
|
|
widget = self.table.indexWidget(index)
|
|
|
|
|
if widget is not None:
|
|
|
|
|
# 从容器widget中获取comboBox
|
|
|
|
|
comboBox = widget.findChild(QComboBox)
|
|
|
|
|
else:
|
|
|
|
|
# 方法2:尝试通过getattr获取委托中的comboBox
|
|
|
|
|
try:
|
|
|
|
|
comboBox = getattr(delegate, cbRow, None)
|
|
|
|
|
except AttributeError:
|
|
|
|
|
# 如果属性不存在,跳过这一行
|
|
|
|
|
try:
|
|
|
|
|
index = self.index(i, int(comboBoxColumn))
|
|
|
|
|
|
|
|
|
|
# 方法1:通过indexWidget获取已存在的comboBox
|
|
|
|
|
widget = self.table.indexWidget(index)
|
|
|
|
|
comboBox = None
|
|
|
|
|
|
|
|
|
|
if widget is not None:
|
|
|
|
|
# 从容器widget中获取comboBox
|
|
|
|
|
comboBox = widget.findChild(QComboBox)
|
|
|
|
|
else:
|
|
|
|
|
# 方法2:尝试通过getattr获取委托中的comboBox
|
|
|
|
|
try:
|
|
|
|
|
delegate = self.table.itemDelegate(index)
|
|
|
|
|
cbRow = str('cb' + str(i) + str(comboBoxColumn))
|
|
|
|
|
comboBox = getattr(delegate, cbRow, None)
|
|
|
|
|
except (AttributeError, IndexError):
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# 检查comboBox对象是否仍然有效
|
|
|
|
|
if (comboBox is None or
|
|
|
|
|
not hasattr(comboBox, 'setCurrentText')):
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
if comboBox is None:
|
|
|
|
|
# 如果comboBox不存在,跳过这一行
|
|
|
|
|
# 尝试设置comboBox的值
|
|
|
|
|
try:
|
|
|
|
|
currentValue = str(self.datas[i][comboBoxColumn])
|
|
|
|
|
comboBox.setCurrentText(currentValue)
|
|
|
|
|
except (RuntimeError, AttributeError, IndexError) as e:
|
|
|
|
|
# 如果设置值失败,跳过这一行
|
|
|
|
|
print(f"设置comboBox值失败 (行 {i}, 列 {comboBoxColumn}): {e}")
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
# 检查comboBox对象是否仍然有效,避免RuntimeError
|
|
|
|
|
if not comboBox or comboBox.isHidden():
|
|
|
|
|
except Exception as e:
|
|
|
|
|
# 捕获所有异常,确保程序不会崩溃
|
|
|
|
|
print(f"刷新comboBox时出错 (行 {i}, 列 {comboBoxColumn}): {e}")
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 根据数据类型设置comboBox的值
|
|
|
|
|
comboBox.setCurrentText(str(self.datas[i][comboBoxColumn]))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -240,75 +249,86 @@ class ModbusButtonDelegate(BaseButtonDelegate):
|
|
|
|
|
painter.fillRect(paint_rect, index.data(Qt.BackgroundRole))
|
|
|
|
|
|
|
|
|
|
if not self.parent().indexWidget(index):
|
|
|
|
|
button1 = QPushButton()
|
|
|
|
|
button1.setIcon(qtawesome.icon('fa.play', color='#1fbb6f'))
|
|
|
|
|
button1.setToolTip("启动强制")
|
|
|
|
|
|
|
|
|
|
button2 = QPushButton()
|
|
|
|
|
button2.setIcon(qtawesome.icon('fa.pencil', color='#4c8cf2'))
|
|
|
|
|
button2.setToolTip("编辑变量")
|
|
|
|
|
|
|
|
|
|
button3 = QPushButton()
|
|
|
|
|
button3.setIcon(qtawesome.icon('fa.trash', color='#ff6d6d'))
|
|
|
|
|
button3.setToolTip("删除变量")
|
|
|
|
|
|
|
|
|
|
button4 = QPushButton()
|
|
|
|
|
button4.setIcon(qtawesome.icon('fa.line-chart', color='#393c4e'))
|
|
|
|
|
button4.setToolTip("趋势图")
|
|
|
|
|
|
|
|
|
|
comboBox = QComboBox(self.parent())
|
|
|
|
|
comboBox.addItem('int', 0)
|
|
|
|
|
comboBox.addItem('ABCD', 1)
|
|
|
|
|
comboBox.addItem('CDAB', 2)
|
|
|
|
|
comboBox.addItem('BADC', 3)
|
|
|
|
|
comboBox.addItem('DCBA', 4)
|
|
|
|
|
comboBox.setCurrentText(str(self.parent().model.datas[index.row()][index.column()]))
|
|
|
|
|
comboBox.setToolTip("字节序")
|
|
|
|
|
|
|
|
|
|
comboBox.currentIndexChanged.connect(self.indexChange)
|
|
|
|
|
button1.clicked.connect(self.start_action)
|
|
|
|
|
button2.clicked.connect(self.edit_action)
|
|
|
|
|
button3.clicked.connect(self.delete_action)
|
|
|
|
|
button4.clicked.connect(self.trend_action)
|
|
|
|
|
|
|
|
|
|
button2.oldName = False
|
|
|
|
|
button2.isEdit = True
|
|
|
|
|
button3.editButton = button2
|
|
|
|
|
|
|
|
|
|
button1.index = [index.row(), index.column()]
|
|
|
|
|
button2.index = [index.row(), index.column()]
|
|
|
|
|
button3.index = [index.row(), index.column()]
|
|
|
|
|
button4.index = [index.row(), index.column()]
|
|
|
|
|
comboBox.index = [index.row(), index.column()]
|
|
|
|
|
|
|
|
|
|
data = self.parent().model.datas[index.row()]
|
|
|
|
|
for x in data[:-3]:
|
|
|
|
|
if x != '':
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
button2.isEdit = False
|
|
|
|
|
button2.setIcon(qtawesome.icon('fa.save', color='#1fbb6f'))
|
|
|
|
|
button2.setToolTip("保存变量")
|
|
|
|
|
self.parent().model.editableList.append(button2.index[0])
|
|
|
|
|
|
|
|
|
|
hboxLayout = QHBoxLayout()
|
|
|
|
|
hboxLayout.addWidget(comboBox)
|
|
|
|
|
hboxLayout.addWidget(button1)
|
|
|
|
|
hboxLayout.addWidget(button2)
|
|
|
|
|
hboxLayout.addWidget(button3)
|
|
|
|
|
hboxLayout.addWidget(button4)
|
|
|
|
|
hboxLayout.setContentsMargins(2, 2, 2, 2)
|
|
|
|
|
hboxLayout.setAlignment(Qt.AlignCenter)
|
|
|
|
|
hboxLayout.setSpacing(3)
|
|
|
|
|
|
|
|
|
|
widget = QWidget()
|
|
|
|
|
widget.setLayout(hboxLayout)
|
|
|
|
|
widget.setStyleSheet("QComboBox { background-color: transparent; }")
|
|
|
|
|
# 所有下拉框使用统一样式
|
|
|
|
|
widget.setObjectName('ModbusButtonWidget')
|
|
|
|
|
comboBox.setObjectName('ModbusOrderBox')
|
|
|
|
|
|
|
|
|
|
self.parent().setIndexWidget(index, widget)
|
|
|
|
|
try:
|
|
|
|
|
button1 = QPushButton()
|
|
|
|
|
button1.setIcon(qtawesome.icon('fa.play', color='#1fbb6f'))
|
|
|
|
|
button1.setToolTip("启动强制")
|
|
|
|
|
|
|
|
|
|
button2 = QPushButton()
|
|
|
|
|
button2.setIcon(qtawesome.icon('fa.pencil', color='#4c8cf2'))
|
|
|
|
|
button2.setToolTip("编辑变量")
|
|
|
|
|
|
|
|
|
|
button3 = QPushButton()
|
|
|
|
|
button3.setIcon(qtawesome.icon('fa.trash', color='#ff6d6d'))
|
|
|
|
|
button3.setToolTip("删除变量")
|
|
|
|
|
|
|
|
|
|
button4 = QPushButton()
|
|
|
|
|
button4.setIcon(qtawesome.icon('fa.line-chart', color='#393c4e'))
|
|
|
|
|
button4.setToolTip("趋势图")
|
|
|
|
|
|
|
|
|
|
comboBox = QComboBox(self.parent())
|
|
|
|
|
comboBox.addItem('int', 0)
|
|
|
|
|
comboBox.addItem('ABCD', 1)
|
|
|
|
|
comboBox.addItem('CDAB', 2)
|
|
|
|
|
comboBox.addItem('BADC', 3)
|
|
|
|
|
comboBox.addItem('DCBA', 4)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
comboBox.setCurrentText(str(self.parent().model.datas[index.row()][index.column()]))
|
|
|
|
|
except (IndexError, RuntimeError):
|
|
|
|
|
# 如果数据访问失败,设置默认值
|
|
|
|
|
comboBox.setCurrentIndex(0)
|
|
|
|
|
|
|
|
|
|
comboBox.setToolTip("字节序")
|
|
|
|
|
|
|
|
|
|
comboBox.currentIndexChanged.connect(self.indexChange)
|
|
|
|
|
button1.clicked.connect(self.start_action)
|
|
|
|
|
button2.clicked.connect(self.edit_action)
|
|
|
|
|
button3.clicked.connect(self.delete_action)
|
|
|
|
|
button4.clicked.connect(self.trend_action)
|
|
|
|
|
|
|
|
|
|
button2.oldName = False
|
|
|
|
|
button2.isEdit = True
|
|
|
|
|
button3.editButton = button2
|
|
|
|
|
|
|
|
|
|
button1.index = [index.row(), index.column()]
|
|
|
|
|
button2.index = [index.row(), index.column()]
|
|
|
|
|
button3.index = [index.row(), index.column()]
|
|
|
|
|
button4.index = [index.row(), index.column()]
|
|
|
|
|
comboBox.index = [index.row(), index.column()]
|
|
|
|
|
|
|
|
|
|
data = self.parent().model.datas[index.row()]
|
|
|
|
|
for x in data[:-3]:
|
|
|
|
|
if x != '':
|
|
|
|
|
break
|
|
|
|
|
else:
|
|
|
|
|
button2.isEdit = False
|
|
|
|
|
button2.setIcon(qtawesome.icon('fa.save', color='#1fbb6f'))
|
|
|
|
|
button2.setToolTip("保存变量")
|
|
|
|
|
self.parent().model.editableList.append(button2.index[0])
|
|
|
|
|
|
|
|
|
|
hboxLayout = QHBoxLayout()
|
|
|
|
|
hboxLayout.addWidget(comboBox)
|
|
|
|
|
hboxLayout.addWidget(button1)
|
|
|
|
|
hboxLayout.addWidget(button2)
|
|
|
|
|
hboxLayout.addWidget(button3)
|
|
|
|
|
hboxLayout.addWidget(button4)
|
|
|
|
|
hboxLayout.setContentsMargins(2, 2, 2, 2)
|
|
|
|
|
hboxLayout.setAlignment(Qt.AlignCenter)
|
|
|
|
|
hboxLayout.setSpacing(3)
|
|
|
|
|
|
|
|
|
|
widget = QWidget()
|
|
|
|
|
widget.setLayout(hboxLayout)
|
|
|
|
|
widget.setStyleSheet("QComboBox { background-color: transparent; }")
|
|
|
|
|
# 所有下拉框使用统一样式
|
|
|
|
|
widget.setObjectName('ModbusButtonWidget')
|
|
|
|
|
comboBox.setObjectName('ModbusOrderBox')
|
|
|
|
|
|
|
|
|
|
self.parent().setIndexWidget(index, widget)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
# 捕获异常,确保paint方法不会崩溃
|
|
|
|
|
print(f"创建按钮时出错 (行 {index.row()}, 列 {index.column()}): {e}")
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def indexChange(self):
|
|
|
|
|
sender = self.sender()
|
|
|
|
@ -538,44 +558,65 @@ class ModbusTypeBox(QItemDelegate):
|
|
|
|
|
painter.fillRect(paint_rect, index.data(Qt.BackgroundRole))
|
|
|
|
|
|
|
|
|
|
if (index.column() == 5) and index.row() not in self.parent().model.editableList:
|
|
|
|
|
data = self.parent().model.datas[index.row()]
|
|
|
|
|
comBox = str('cb' + str(index.row()) + str(index.column()))
|
|
|
|
|
setattr(self, comBox, QComboBox())
|
|
|
|
|
comboBox = getattr(self, comBox)
|
|
|
|
|
items = ['Coil Status', 'Input Status', 'Input Register', 'Holding Register']
|
|
|
|
|
comboBox.addItems(items)
|
|
|
|
|
if self.parent().model.datas[index.row()][index.column()] in [0, 1]:
|
|
|
|
|
comboBox.setCurrentIndex(self.parent().model.datas[index.row()][index.column()])
|
|
|
|
|
elif self.parent().model.datas[index.row()][index.column()] in [3, 4]:
|
|
|
|
|
comboBox.setCurrentIndex(self.parent().model.datas[index.row()][index.column()] - 1)
|
|
|
|
|
else:
|
|
|
|
|
comboBox.setCurrentIndex(0)
|
|
|
|
|
|
|
|
|
|
comboBox.currentIndexChanged.connect(self.indexChange)
|
|
|
|
|
comboBox.setObjectName('ModbusTypeBox')
|
|
|
|
|
comboBox.setEditable(True)
|
|
|
|
|
comboBox.lineEdit().setAlignment(Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
hboxLayout = QHBoxLayout()
|
|
|
|
|
hboxLayout.addWidget(comboBox)
|
|
|
|
|
hboxLayout.setContentsMargins(2, 2, 2, 2)
|
|
|
|
|
comboBox.index = [index.row(), index.column()]
|
|
|
|
|
|
|
|
|
|
# 所有下拉框使用统一样式
|
|
|
|
|
comboBox.setObjectName('ModbusTypeBox')
|
|
|
|
|
try:
|
|
|
|
|
data = self.parent().model.datas[index.row()]
|
|
|
|
|
comBox = str('cb' + str(index.row()) + str(index.column()))
|
|
|
|
|
|
|
|
|
|
# 创建容器widget
|
|
|
|
|
containerWidget = QWidget()
|
|
|
|
|
containerWidget.setStyleSheet("QComboBox { background-color: transparent; }")
|
|
|
|
|
|
|
|
|
|
# 创建新的comboBox,设置正确的父对象
|
|
|
|
|
comboBox = QComboBox(containerWidget)
|
|
|
|
|
comboBox.setObjectName('ModbusTypeBox')
|
|
|
|
|
comboBox.setEditable(True)
|
|
|
|
|
comboBox.lineEdit().setAlignment(Qt.AlignCenter)
|
|
|
|
|
comboBox.index = [index.row(), index.column()]
|
|
|
|
|
|
|
|
|
|
# 添加选项
|
|
|
|
|
items = ['Coil Status', 'Input Status', 'Input Register', 'Holding Register']
|
|
|
|
|
comboBox.addItems(items)
|
|
|
|
|
|
|
|
|
|
# 设置当前值
|
|
|
|
|
try:
|
|
|
|
|
currentValue = self.parent().model.datas[index.row()][index.column()]
|
|
|
|
|
if currentValue in [0, 1]:
|
|
|
|
|
comboBox.setCurrentIndex(currentValue)
|
|
|
|
|
elif currentValue in [3, 4]:
|
|
|
|
|
comboBox.setCurrentIndex(currentValue - 1)
|
|
|
|
|
else:
|
|
|
|
|
comboBox.setCurrentIndex(0)
|
|
|
|
|
except (IndexError, RuntimeError, AttributeError):
|
|
|
|
|
comboBox.setCurrentIndex(0)
|
|
|
|
|
|
|
|
|
|
if str(data[index.column()]):
|
|
|
|
|
comboBox.setEnabled(False)
|
|
|
|
|
comboBox.setProperty('disabled', True)
|
|
|
|
|
else:
|
|
|
|
|
comboBox.setEnabled(True)
|
|
|
|
|
comboBox.setProperty('disabled', False)
|
|
|
|
|
# 连接信号
|
|
|
|
|
comboBox.currentIndexChanged.connect(self.indexChange)
|
|
|
|
|
|
|
|
|
|
# 设置启用状态
|
|
|
|
|
if str(data[index.column()]):
|
|
|
|
|
comboBox.setEnabled(False)
|
|
|
|
|
comboBox.setProperty('disabled', True)
|
|
|
|
|
else:
|
|
|
|
|
comboBox.setEnabled(True)
|
|
|
|
|
comboBox.setProperty('disabled', False)
|
|
|
|
|
|
|
|
|
|
# 创建布局
|
|
|
|
|
hboxLayout = QHBoxLayout()
|
|
|
|
|
hboxLayout.addWidget(comboBox)
|
|
|
|
|
hboxLayout.setContentsMargins(2, 2, 2, 2)
|
|
|
|
|
containerWidget.setLayout(hboxLayout)
|
|
|
|
|
|
|
|
|
|
# 设置索引widget
|
|
|
|
|
self.parent().setIndexWidget(index, containerWidget)
|
|
|
|
|
self.parent().openPersistentEditor(index)
|
|
|
|
|
|
|
|
|
|
widget = QWidget()
|
|
|
|
|
widget.setStyleSheet("QComboBox { background-color: transparent; }")
|
|
|
|
|
widget.setLayout(hboxLayout)
|
|
|
|
|
self.parent().setIndexWidget(index, widget)
|
|
|
|
|
self.parent().openPersistentEditor(index)
|
|
|
|
|
# 保存comboBox引用到委托对象,以便refreshComboBox能够找到它
|
|
|
|
|
setattr(self, comBox, comboBox)
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
# 捕获异常,确保paint方法不会崩溃
|
|
|
|
|
print(f"创建ModbusTypeBox时出错 (行 {index.row()}, 列 {index.column()}): {e}")
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def indexChange(self):
|
|
|
|
|
sender = self.sender()
|
|
|
|
@ -602,28 +643,53 @@ class ModbusVarModelBox(QItemDelegate):
|
|
|
|
|
|
|
|
|
|
# 本地值、模拟值、远程值 对应 0, 1, 2
|
|
|
|
|
if (index.column() == self.comBoxColumn) and not self.parent().indexWidget(index):
|
|
|
|
|
data = self.parent().model.datas[index.row()]
|
|
|
|
|
comBox = str('cb' + str(index.row()) + str(index.column()))
|
|
|
|
|
setattr(self, comBox, QComboBox())
|
|
|
|
|
comboBox = getattr(self, comBox)
|
|
|
|
|
items = ['本地值', '模拟值', '远程值']
|
|
|
|
|
comboBox.addItems(items)
|
|
|
|
|
comboBox.setCurrentText(str(self.parent().model.datas[index.row()][index.column()]))
|
|
|
|
|
|
|
|
|
|
comboBox.currentIndexChanged.connect(self.indexChange)
|
|
|
|
|
comboBox.setObjectName('ModbusVarModelBox')
|
|
|
|
|
comboBox.setEditable(True)
|
|
|
|
|
comboBox.lineEdit().setAlignment(Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
hboxLayout = QHBoxLayout()
|
|
|
|
|
hboxLayout.addWidget(comboBox)
|
|
|
|
|
hboxLayout.setContentsMargins(2, 2, 2, 2)
|
|
|
|
|
comboBox.index = [index.row(), index.column()]
|
|
|
|
|
widget = QWidget()
|
|
|
|
|
widget.setStyleSheet("QComboBox { background-color: transparent; }")
|
|
|
|
|
widget.setLayout(hboxLayout)
|
|
|
|
|
self.parent().setIndexWidget(index, widget)
|
|
|
|
|
self.parent().openPersistentEditor(index)
|
|
|
|
|
try:
|
|
|
|
|
data = self.parent().model.datas[index.row()]
|
|
|
|
|
comBox = str('cb' + str(index.row()) + str(index.column()))
|
|
|
|
|
|
|
|
|
|
# 创建容器widget
|
|
|
|
|
containerWidget = QWidget()
|
|
|
|
|
containerWidget.setStyleSheet("QComboBox { background-color: transparent; }")
|
|
|
|
|
|
|
|
|
|
# 创建新的comboBox,设置正确的父对象
|
|
|
|
|
comboBox = QComboBox(containerWidget)
|
|
|
|
|
comboBox.setObjectName('ModbusVarModelBox')
|
|
|
|
|
comboBox.setEditable(True)
|
|
|
|
|
comboBox.lineEdit().setAlignment(Qt.AlignCenter)
|
|
|
|
|
comboBox.index = [index.row(), index.column()]
|
|
|
|
|
|
|
|
|
|
# 添加选项
|
|
|
|
|
items = ['本地值', '模拟值', '远程值']
|
|
|
|
|
comboBox.addItems(items)
|
|
|
|
|
|
|
|
|
|
# 连接信号
|
|
|
|
|
comboBox.currentIndexChanged.connect(self.indexChange)
|
|
|
|
|
|
|
|
|
|
# 设置当前值
|
|
|
|
|
try:
|
|
|
|
|
currentValue = str(self.parent().model.datas[index.row()][index.column()])
|
|
|
|
|
comboBox.setCurrentText(currentValue)
|
|
|
|
|
except (IndexError, RuntimeError, AttributeError):
|
|
|
|
|
# 如果设置值失败,使用默认值
|
|
|
|
|
comboBox.setCurrentIndex(0)
|
|
|
|
|
|
|
|
|
|
# 创建布局
|
|
|
|
|
hboxLayout = QHBoxLayout()
|
|
|
|
|
hboxLayout.addWidget(comboBox)
|
|
|
|
|
hboxLayout.setContentsMargins(2, 2, 2, 2)
|
|
|
|
|
containerWidget.setLayout(hboxLayout)
|
|
|
|
|
|
|
|
|
|
# 设置索引widget
|
|
|
|
|
self.parent().setIndexWidget(index, containerWidget)
|
|
|
|
|
self.parent().openPersistentEditor(index)
|
|
|
|
|
|
|
|
|
|
# 保存comboBox引用到委托对象,以便refreshComboBox能够找到它
|
|
|
|
|
setattr(self, comBox, comboBox)
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
# 捕获异常,确保paint方法不会崩溃
|
|
|
|
|
print(f"创建comboBox时出错 (行 {index.row()}, 列 {index.column()}): {e}")
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def indexChange(self):
|
|
|
|
|
sender = self.sender()
|
|
|
|
|