dircou 发表于 2024-9-18 12:25:43

pyqt5 model.dataChanged死循环

想弄一个更改了单元格内容后自动检测当前单元格内容及补充后面内容的表格,所以使用了
pyqt5 tableview表格
self.model.dataChanged.connect(self.tableEdit)

tableEdit代码
    def tableEdit(self,vmodeIndex):
      # tableView处理事件
      # print('单元格被修改! row %s clou %s'%(vmodeIndex.row(),vmodeIndex.column()))
      # 单元格跨度检测 是否是合并单元格!等于1则不是,反之则是合并单元格!
      # print('rowSpan:%s'%self.ui.tableView_V.rowSpan(vmodeIndex.row(),vmodeIndex.column()))
      if vmodeIndex.column() == 3:
            row, column = vmodeIndex.row(),vmodeIndex.column()
      # 判断是否在位置列进行双击! abs()取绝对值,负数变正数;round()四舍五入,取整数!
            # print(self.model.index(row,3).data())
            data = self.model.index(row,3).data()
            print(f'Data数据:{data}')
            # 判断当前数据是否是纯数字!
            if not data.isdigit():
                item = QStandardItem('0')
                self.model.setItem(row, 7, item)
                item = QStandardItem('0')
                self.model.setItem(row, 4, item)
                return
            if int(data) < 3500 or int(data) > 9500:
                # 想要的效果是修改后的内容如果不在3500-9500之间就把当前单元格设置个背景色或改变字体颜色,可都失败!
                print('内容大于或小于系统预设值!')
                item = QStandardItem(data)
                # #self.model.setItem(vmodeIndex,)
                item.setForeground(QBrush(QColor(255, 0, 0)))# 设置字体颜色
                # # item.setBackground(QBrush(Qt.red))
                self.model.setItem(row, column - 1, item)        # 到这后就一直循环!
            else:

到 self.model.setItem(row, column - 1, item) 设置mode后死循环崩溃!
有大佬可以指点下嘛,刚学摸索中!!

FishC 发表于 2024-9-18 12:37:07

你遇到死循环的原因是:在 `dataChanged` 信号的槽函数 `tableEdit` 中调用 `self.model.setItem` 会再次触发 `dataChanged` 信号,从而导致死循环。

要解决这个问题,可以在更新单元格数据的过程中临时断开 `dataChanged` 信号,然后在更新完数据后再重新连接。以下是修改后的代码示例:

class YourClass:
    def __init__(self):
      # 初始化代码
      self.model.dataChanged.connect(self.tableEdit)

    def tableEdit(self, vmodeIndex):
      # 处理事件的代码
      if vmodeIndex.column() == 3:
            row, column = vmodeIndex.row(), vmodeIndex.column()
            data = self.model.index(row, 3).data()
            print(f'Data数据:{data}')

            if not data.isdigit():
                self.model.dataChanged.disconnect(self.tableEdit)# 断开信号连接
                self.model.setItem(row, 7, QStandardItem('0'))
                self.model.setItem(row, 4, QStandardItem('0'))
                self.model.dataChanged.connect(self.tableEdit)# 重新连接信号
                return

            if int(data) < 3500 or int(data) > 9500:
                print('内容大于或小于系统预设值!')
                item = QStandardItem(data)
                item.setForeground(QBrush(QColor(255, 0, 0)))# 设置字体颜色

                self.model.dataChanged.disconnect(self.tableEdit)# 断开信号连接
                self.model.setItem(row, column - 1, item)# 更新数据
                self.model.dataChanged.connect(self.tableEdit)# 重新连接信号
            else:
                # 如果需要增加其他处理逻辑,可以在这里编写
                pass

该方法通过在数据更新前后断开和重新连接 `dataChanged` 信号,防止了因数据更新引起的信号递归触发,避免了死循环的发生。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

dircou 发表于 2024-9-18 13:13:23

非常感谢!

FishC 发表于 2024-9-18 13:13:38

dircou 发表于 2024-09-18 13:13
非常感谢!

为了避免死循环问题,你可以在更新单元格数据时临时断开 `dataChanged` 信号,然后在更新完成后重新连接信号。以下是一个示例代码,展示了如何实现这一点:

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QBrush, QColor
from PyQt5.QtWidgets import QStandardItem

def tableEdit(self, vmodeIndex):
    # 临时断开 dataChanged 信号
    self.model.dataChanged.disconnect(self.tableEdit)
   
    try:
      if vmodeIndex.column() == 3:
            row, column = vmodeIndex.row(), vmodeIndex.column()
            data = self.model.index(row, 3).data()
            print(f'Data数据:{data}')
            
            if not data.isdigit():
                item = QStandardItem('0')
                self.model.setItem(row, 7, item)
                item = QStandardItem('0')
                self.model.setItem(row, 4, item)
            elif int(data) < 3500 or int(data) > 9500:
                print('内容大于或小于系统预设值!')
                item = QStandardItem(data)
                item.setForeground(QBrush(QColor(255, 0, 0)))# 设置字体颜色
                self.model.setItem(row, column - 1, item)
    finally:
      # 重新连接 dataChanged 信号
      self.model.dataChanged.connect(self.tableEdit)

在这个示例中,我们在更新单元格数据之前断开 `dataChanged` 信号,更新完成后再重新连接信号。这样可以避免在更新单元格数据时触发 `dataChanged` 信号,从而避免死循环。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: pyqt5 model.dataChanged死循环