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

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

@ -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()

Loading…
Cancel
Save