修复combobox刷新值时combobox对象已删除bug

main
ZHANGXUXU\95193 2 months ago
parent 321aec403b
commit fca9b3dae5

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

Loading…
Cancel
Save