求助调试wxPython RuntimeError:JLCPCBTools对象已被删除
RuntimeError: wrapped C/C++ object of type JLCPCBTools has been deleted 排查与解决
问题概述
调试kicad-jlcpcb-tools插件时触发wxPython报错:RuntimeError: wrapped C/C++ object of type JLCPCBTools has been deleted,怀疑与队列或对象生命周期管理不当有关,但缺乏明确排查方向。核心日志事件发送逻辑如下:
def emit(self, record): """Marshal the event over to the main thread.""" msg = self.format(record) wx.QueueEvent(self.event_destination, LogboxAppendEvent( msg=f"{msg}\n" ) )
核心原因分析
这个错误的本质是尝试访问已被销毁的wxPython底层C++对象。wxPython的UI对象由C层管理,当Python层引用的对象在C侧被销毁后,继续调用该对象的方法或通过它发送事件就会触发此报错。
具体排查与修复方向
检查
event_destination的生命周期
确认self.event_destination(即JLCPCBTools实例)在emit方法执行时是否仍处于存活状态。常见场景是插件窗口已关闭销毁,但后台线程仍在运行并调用emit发送日志事件。在事件发送前增加对象有效性校验
在emit方法中先判断目标对象是否可用,避免向已销毁的对象发送事件:def emit(self, record): """Marshal the event over to the main thread.""" # 校验目标对象是否存活 if not hasattr(self, 'event_destination') or not self.event_destination: return msg = self.format(record) wx.QueueEvent(self.event_destination, LogboxAppendEvent(msg=f"{msg}\n"))完善日志处理器的注销逻辑
在插件窗口关闭的回调(如OnClose)中,主动移除自定义的StreamHandler,确保后台日志不再尝试向已销毁的UI对象发送事件:def OnClose(self, event): # 移除日志处理器 logger = logging.getLogger() for handler in logger.handlers[:]: if isinstance(handler, YourCustomStreamHandler): logger.removeHandler(handler) self.Destroy()确保线程安全的对象访问
如果日志处理在后台线程执行,需通过锁或状态标记控制对象的访问,避免销毁对象的同时有线程正在使用它。比如添加一个_is_alive标记,在窗口关闭时设为False,emit方法先检查该标记。
内容的提问来源于stack exchange,提问作者Chris Morgan
相关产品推荐
相关产品推荐

