鱼C论坛

 找回密码
 立即注册
查看: 725|回复: 3

[已解决]pyqt5 model.dataChanged死循环

[复制链接]
发表于 2024-9-18 12:25:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

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


到 self.model.setItem(row, column - 1, item) 设置mode后死循环崩溃!
有大佬可以指点下嘛,刚学摸索中!!
最佳答案
2024-9-18 12:37:07
你遇到死循环的原因是:在 `dataChanged` 信号的槽函数 `tableEdit` 中调用 `self.model.setItem` 会再次触发 `dataChanged` 信号,从而导致死循环。

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

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

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

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

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

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


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2024-9-18 12:37:07 | 显示全部楼层    本楼为最佳答案   
你遇到死循环的原因是:在 `dataChanged` 信号的槽函数 `tableEdit` 中调用 `self.model.setItem` 会再次触发 `dataChanged` 信号,从而导致死循环。

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

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

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

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

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

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


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-9-18 13:13:23 | 显示全部楼层
非常感谢!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-9-18 13:13:38 | 显示全部楼层


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

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

  4. def tableEdit(self, vmodeIndex):
  5.     # 临时断开 dataChanged 信号
  6.     self.model.dataChanged.disconnect(self.tableEdit)
  7.    
  8.     try:
  9.         if vmodeIndex.column() == 3:
  10.             row, column = vmodeIndex.row(), vmodeIndex.column()
  11.             data = self.model.index(row, 3).data()
  12.             print(f'Data数据:{data}')
  13.             
  14.             if not data.isdigit():
  15.                 item = QStandardItem('0')
  16.                 self.model.setItem(row, 7, item)
  17.                 item = QStandardItem('0')
  18.                 self.model.setItem(row, 4, item)
  19.             elif int(data) < 3500 or int(data) > 9500:
  20.                 print('内容大于或小于系统预设值!')
  21.                 item = QStandardItem(data)
  22.                 item.setForeground(QBrush(QColor(255, 0, 0)))  # 设置字体颜色
  23.                 self.model.setItem(row, column - 1, item)
  24.     finally:
  25.         # 重新连接 dataChanged 信号
  26.         self.model.dataChanged.connect(self.tableEdit)
复制代码


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

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-21 22:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表