You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助调试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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:34:54