PyQt6贝塞尔曲线程序递归错误排查求助
递归问题排查与解决
核心原因分析
你遇到的RecursionError大概率是setSceneRect触发了循环调用:要么是setSceneRect触发了场景变化信号(比如sceneRectChanged),而你的代码在该信号的回调函数中又重新计算并调用了setSceneRect;要么是每次设置新的场景矩形后,你的边界判断逻辑误判为“仍超出尺寸”,导致再次调用setSceneRect,形成无限递归。
排查步骤
添加调用栈日志:在调用
setSceneRect的前后加入调用栈打印,精准定位递归来源:import traceback # 调用setSceneRect前 print("调试3:准备调用setSceneRect") traceback.print_stack() self.scene.setSceneRect(new_rect) print("调试4:setSceneRect调用完成")查看日志里的调用链,确认每次
setSceneRect是不是被同一个函数反复触发。检查信号绑定:确认是否将
sceneRectChanged信号绑定到了会触发场景矩形调整的函数上。如果有,这就是循环的源头。
解决方法
1. 避免重复调用setSceneRect
在设置新场景矩形前,先和当前矩形做对比,只有当差异超过阈值(避免浮点精度问题)时才执行设置:
current_rect = self.scene.sceneRect() # 这里替换成你计算新场景矩形的逻辑 new_rect = QRectF(min_x, min_y, max_width, max_height) # 设定微小阈值,避免无意义的重复调用 threshold = 1e-6 if (abs(new_rect.x() - current_rect.x()) > threshold or abs(new_rect.y() - current_rect.y()) > threshold or abs(new_rect.width() - current_rect.width()) > threshold or abs(new_rect.height() - current_rect.height()) > threshold): self.scene.setSceneRect(new_rect)
2. 调整场景矩形的触发时机
不要在mouseMoveEvent中实时调用setSceneRect,而是在拖动结束的mouseReleaseEvent中一次性计算并更新场景矩形,减少触发频率,避免递归触发。
3. 切断信号循环
如果确实绑定了sceneRectChanged信号到调整函数,要么解除该绑定,要么在回调函数中添加判断,避免在信号触发时再次调用setSceneRect:
def on_scene_rect_changed(self, new_rect): # 只在特定条件下执行调整逻辑,而非每次场景矩形变化都触发 if not self.is_dragging: # 假设is_dragging是拖动状态标记 self.adjust_scene_rect()
内容的提问来源于stack exchange,提问作者derGraph
相关产品推荐
相关产品推荐

