Nuke关闭时触发ValueError异常,try/except无法捕获求助
问题原因
关闭Nuke时触发报错的核心原因有两点:
- 回调移除失败:你通过
nuke.addOnScriptClose添加的移除回调逻辑中,nuke.root()在Nuke关闭流程后期已变成无效的Python对象(节点已被销毁/解除关联),导致nuke.removeKnobChanged执行失败,原本绑定的on_checkbox_clicked回调未被正确移除。 - 回调触发时节点无效:Nuke关闭阶段仍会尝试执行残留的knobChanged回调,此时回调绑定的Root节点已失效,底层遍历回调列表时触发
PythonObject未关联节点的错误,而你的回调函数内的try-except仅能捕获nuke.root()调用的异常,无法覆盖底层回调遍历的错误。
解决方法
方法1:优化回调绑定与移除逻辑
移除回调时不依赖实时的Root节点引用,仅通过nodeClass参数匹配回调,同时调整回调函数内的节点获取方式:
import nuke def on_checkbox_clicked(): try: # 获取当前触发回调的节点,而非直接调用nuke.root() current_node = nuke.thisNode() if not current_node or current_node.Class() != 'Root': return # 此处编写你的复选框逻辑,例如启用/禁用自定义旋钮 # 示例:current_node.knob("custom_knob").setEnabled(current_node.knob("your_checkbox").value()) except (ValueError, AttributeError) as er: print(f"回调执行异常: {er}") # 仅通过nodeClass绑定回调,无需指定node参数 nuke.addKnobChanged(on_checkbox_clicked, nodeClass='Root') # 移除时同样仅用nodeClass匹配 nuke.addOnScriptClose(lambda: nuke.removeKnobChanged(on_checkbox_clicked, nodeClass='Root'))
方法2:提前保存Root节点引用(备选)
如果必须指定node参数绑定回调,可以提前保存Root节点的引用,避免在onScriptClose时调用失效的nuke.root():
import nuke # 提前保存Root节点引用 root_ref = nuke.root() def on_checkbox_clicked(): try: if not root_ref: return # 此处编写你的复选框逻辑 except (ValueError, AttributeError) as er: print(f"回调执行异常: {er}") nuke.addKnobChanged(on_checkbox_clicked, node=root_ref) nuke.addOnScriptClose(lambda: nuke.removeKnobChanged(on_checkbox_clicked, node=root_ref))
关键注意点
- 避免在Nuke关闭阶段依赖
nuke.root()的实时调用,此时节点资源已开始回收。 - 回调函数内尽量使用
nuke.thisNode()获取触发回调的节点,而非硬编码调用nuke.root(),提升兼容性。 - 扩展异常捕获的类型(比如
AttributeError),覆盖节点失效后访问旋钮可能出现的错误。
内容的提问来源于stack exchange,提问作者Ciasto piekarz
相关产品推荐
相关产品推荐

