修复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: if widget is not None:
# 从容器widget中获取comboBox # 从容器widget中获取comboBox
comboBox = widget.findChild(QComboBox) comboBox = widget.findChild(QComboBox)
else: else:
# 方法2尝试通过getattr获取委托中的comboBox # 方法2尝试通过getattr获取委托中的comboBox
try: try:
delegate = self.table.itemDelegate(index)
cbRow = str('cb' + str(i) + str(comboBoxColumn))
comboBox = getattr(delegate, cbRow, None) comboBox = getattr(delegate, cbRow, None)
except AttributeError: except (AttributeError, IndexError):
# 如果属性不存在,跳过这一行
continue continue
if comboBox is None: # 检查comboBox对象是否仍然有效
# 如果comboBox不存在跳过这一行 if (comboBox is None or
not hasattr(comboBox, 'setCurrentText')):
continue continue
# 检查comboBox对象是否仍然有效避免RuntimeError # 尝试设置comboBox的值
if not comboBox or comboBox.isHidden(): try:
currentValue = str(self.datas[i][comboBoxColumn])
comboBox.setCurrentText(currentValue)
except (RuntimeError, AttributeError, IndexError) as e:
# 如果设置值失败,跳过这一行
print(f"设置comboBox值失败 (行 {i}, 列 {comboBoxColumn}): {e}")
continue continue
except Exception as e:
# 根据数据类型设置comboBox的值 # 捕获所有异常,确保程序不会崩溃
comboBox.setCurrentText(str(self.datas[i][comboBoxColumn])) print(f"刷新comboBox时出错 (行 {i}, 列 {comboBoxColumn}): {e}")
continue
@ -240,6 +249,7 @@ 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):
try:
button1 = QPushButton() button1 = QPushButton()
button1.setIcon(qtawesome.icon('fa.play', color='#1fbb6f')) button1.setIcon(qtawesome.icon('fa.play', color='#1fbb6f'))
button1.setToolTip("启动强制") button1.setToolTip("启动强制")
@ -262,7 +272,13 @@ class ModbusButtonDelegate(BaseButtonDelegate):
comboBox.addItem('CDAB', 2) comboBox.addItem('CDAB', 2)
comboBox.addItem('BADC', 3) comboBox.addItem('BADC', 3)
comboBox.addItem('DCBA', 4) comboBox.addItem('DCBA', 4)
try:
comboBox.setCurrentText(str(self.parent().model.datas[index.row()][index.column()])) comboBox.setCurrentText(str(self.parent().model.datas[index.row()][index.column()]))
except (IndexError, RuntimeError):
# 如果数据访问失败,设置默认值
comboBox.setCurrentIndex(0)
comboBox.setToolTip("字节序") comboBox.setToolTip("字节序")
comboBox.currentIndexChanged.connect(self.indexChange) comboBox.currentIndexChanged.connect(self.indexChange)
@ -309,6 +325,10 @@ class ModbusButtonDelegate(BaseButtonDelegate):
comboBox.setObjectName('ModbusOrderBox') comboBox.setObjectName('ModbusOrderBox')
self.parent().setIndexWidget(index, widget) 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,32 +558,41 @@ 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:
try:
data = self.parent().model.datas[index.row()] data = self.parent().model.datas[index.row()]
comBox = str('cb' + str(index.row()) + str(index.column())) 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) # 创建容器widget
containerWidget = QWidget()
containerWidget.setStyleSheet("QComboBox { background-color: transparent; }")
# 创建新的comboBox设置正确的父对象
comboBox = QComboBox(containerWidget)
comboBox.setObjectName('ModbusTypeBox') comboBox.setObjectName('ModbusTypeBox')
comboBox.setEditable(True) comboBox.setEditable(True)
comboBox.lineEdit().setAlignment(Qt.AlignCenter) comboBox.lineEdit().setAlignment(Qt.AlignCenter)
hboxLayout = QHBoxLayout()
hboxLayout.addWidget(comboBox)
hboxLayout.setContentsMargins(2, 2, 2, 2)
comboBox.index = [index.row(), index.column()] comboBox.index = [index.row(), index.column()]
# 所有下拉框使用统一样式 # 添加选项
comboBox.setObjectName('ModbusTypeBox') 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)
# 连接信号
comboBox.currentIndexChanged.connect(self.indexChange)
# 设置启用状态
if str(data[index.column()]): if str(data[index.column()]):
comboBox.setEnabled(False) comboBox.setEnabled(False)
comboBox.setProperty('disabled', True) comboBox.setProperty('disabled', True)
@ -571,12 +600,24 @@ class ModbusTypeBox(QItemDelegate):
comboBox.setEnabled(True) comboBox.setEnabled(True)
comboBox.setProperty('disabled', False) comboBox.setProperty('disabled', False)
widget = QWidget() # 创建布局
widget.setStyleSheet("QComboBox { background-color: transparent; }") hboxLayout = QHBoxLayout()
widget.setLayout(hboxLayout) hboxLayout.addWidget(comboBox)
self.parent().setIndexWidget(index, widget) hboxLayout.setContentsMargins(2, 2, 2, 2)
containerWidget.setLayout(hboxLayout)
# 设置索引widget
self.parent().setIndexWidget(index, containerWidget)
self.parent().openPersistentEditor(index) 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): def indexChange(self):
sender = self.sender() sender = self.sender()
index = sender.currentIndex() index = sender.currentIndex()
@ -602,29 +643,54 @@ 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):
try:
data = self.parent().model.datas[index.row()] data = self.parent().model.datas[index.row()]
comBox = str('cb' + str(index.row()) + str(index.column())) 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) # 创建容器widget
containerWidget = QWidget()
containerWidget.setStyleSheet("QComboBox { background-color: transparent; }")
# 创建新的comboBox设置正确的父对象
comboBox = QComboBox(containerWidget)
comboBox.setObjectName('ModbusVarModelBox') comboBox.setObjectName('ModbusVarModelBox')
comboBox.setEditable(True) comboBox.setEditable(True)
comboBox.lineEdit().setAlignment(Qt.AlignCenter) 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 = QHBoxLayout()
hboxLayout.addWidget(comboBox) hboxLayout.addWidget(comboBox)
hboxLayout.setContentsMargins(2, 2, 2, 2) hboxLayout.setContentsMargins(2, 2, 2, 2)
comboBox.index = [index.row(), index.column()] containerWidget.setLayout(hboxLayout)
widget = QWidget()
widget.setStyleSheet("QComboBox { background-color: transparent; }") # 设置索引widget
widget.setLayout(hboxLayout) self.parent().setIndexWidget(index, containerWidget)
self.parent().setIndexWidget(index, widget)
self.parent().openPersistentEditor(index) 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()
modbusType = self.parent().modbusType modbusType = self.parent().modbusType

Loading…
Cancel
Save