wxPython + weakref proxy =关闭wx.Frame不会产生无

时间:2016-09-20 08:33:05

标签: python wxpython weak-references

我目前正在使用具有两个窗口的wxWigets创建一个Python应用程序。第一个是主“控制器”窗口,第二个窗口是数据显示窗口。

我希望第一个窗口有一些机制可以知道第二个窗口已经生成的位置,如果是,则由用户关闭。我虽然使用Python的weakref.proxy(),因为基于我对该语言的一点理解,似乎如果一个对象被关闭/销毁/解除分配/ GC,那么任何调用我的代理的尝试都将返回{{1 }},可以使用Python的None / is None运算符方便地检查。

只要窗口生成一次,代理就会按预期工作,如果窗口尚未生成,则返回is not None,否则返回对象的引用。但是,只要关闭辅助窗口,代理对象就不会按预期恢复为None,并且我的应用程序将因None而崩溃。

我记得我之前尝试解决这个问题,我找到的最有效的解决方案是针对内部wx类检查对象的类名,例如:

ReferenceError: weakly-referenced object no longer exists
然而,这对我来说似乎是一个非常讨厌的解决方案,而且我想知道除了上述之外是否还有更好的解决方法。下面是一些重现我的这个问题的基本代码。

if windowObject.__class__.__name__ is not "_wxPyDeadObject": #do stuff

1 个答案:

答案 0 :(得分:3)

正如您所见,当wx小部件对象被销毁时,Python代理对象的类与更改它的类交换,以在您尝试使用它时引发异常。它还有一个__nonzero__方法,所以你可以做这样的事情而不是挖掘对象的内容来找到它的类名:

if not windowObject:
    # it has been destroyed already
    return

要记住的另一件事是顶级窗口在关闭或调用Destroy方法时不会被销毁。相反,它们会被添加到待处理的删除列表中,只要没有更多待处理事件,就会立即对其进行处理。您可以通过调用框架的IsBeingDeleted方法来测试该情况(已关闭但尚未销毁)。此外,UI对象的C ++部分也拥有自己对Python对象的引用,尽管在C ++对象被销毁时将会减少。因此,部分或全部这些事情可能会干扰您的weafref方法。就个人而言,我只会使用如上所述的if语句。短。甜。简单。

P.S。我在这里提到的一些细节是针对wxPython Classic的,而凤凰城的处理方式并不相同。但是,使用上述if语句仍然有效。