diff --git a/UI/VarManages/ModbusModel.py b/UI/VarManages/ModbusModel.py index 3d16852..fe8058d 100644 --- a/UI/VarManages/ModbusModel.py +++ b/UI/VarManages/ModbusModel.py @@ -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()