【问题标题】:wx._core.PyDeadObjectError when switching frames in wxPython?在 wxPython 中切换帧时出现 wx._core.PyDeadObjectError?
【发布时间】:2014-08-04 20:22:27
【问题描述】:

在我的 wx.ComboBox 中的页面之间切换时我遇到了问题。错误似乎是何时更改页面两次以上。这对我来说是一个巨大的错误,我似乎无法找到解决方案。代码:

import wx
ok=[]
class oranges(wx.Frame):

    def __init__(self,parent,id):
        wx.Frame.__init__(self,parent,id,'Testing Sample',size=(1024,768))
        self.frame=wx.Panel(self)
        some_text=wx.StaticText(self.frame,-1,'TEXT',pos=(500,500))
        more_choices=['Home','Page One']
        self.adding=wx.ComboBox(self.frame,choices=more_choices,pos=(300,722),style=wx.CB_READONLY)
        self.Bind(wx.EVT_COMBOBOX,self.addition,self.adding)
    def addition(self,event):
        if self.adding.GetValue()=='Home':
            for i in ok:
                i.Destroy()
            ok.append(wx.StaticText(self.frame,-1,'Oranges',pos=(300,300)))
        elif self.adding.GetValue()=='Page One':
            for i in ok:
                i.Destroy()
            ok.append(wx.StaticText(self.frame,-1,'Apples',pos=(300,300)))
        else: pass
if __name__ =='__main__':
    app = wx.PySimpleApp()
    window = oranges(parent=None,id=-1)
    window.Show()
    app.MainLoop()

提前致谢,我迫不及待地想看到答案!

【问题讨论】:

    标签: python python-2.7 combobox wxpython


    【解决方案1】:

    您收到错误的原因是因为您杀死了 ok 中的对象,但 实际上并未将它们从列表中删除。 这很糟糕,因为您会在其中漂浮着死去的小部件外壳你的程序。当您遍历addition 的每一行时,列表迭代的外观如下:

    第一次:

    for i in ok:                                                      #[]
        i.Destroy()                                                   #[]
    ok.append(wx.StaticText(self.frame,-1,'Oranges',pos=(300,300)))   #[<wx object with oranges>]
    

    第二次:

    for i in ok:                                                      #[<wx object with oranges>]
        i.Destroy()                                                   #[<wx object with oranges>]]
    ok.append(wx.StaticText(self.frame,-1,'Oranges',pos=(300,300)))   #[<dead husk>, <wx object with apples>]
    

    第三次:

    for i in ok:                                                      #[<dead husk>, <wx object with apples>]
        i.Destroy()                                                   #[<dead husk>, <wx object with apples>]
    

    当 Python 循环遍历 Ok 并尝试将 Destroy 应用于死壳时,由于对象已被杀死,它会中断。 杀死此对象不会将其从列表中删除

    我通过在添加新对象之前重置 ok 使您的代码正常工作。 但是,我不得不将ok 设为类属性。以下带有诊断打印语句的工作代码:

    import wx
    class oranges(wx.Frame):
        ok=[]
    
        def __init__(self,parent,id):
            wx.Frame.__init__(self,parent,id,'Testing Sample',size=(1024,768))
            self.frame=wx.Panel(self)
            some_text=wx.StaticText(self.frame,-1,'TEXT',pos=(500,500))
            more_choices=['Home','Page One']
            self.adding=wx.ComboBox(self.frame,choices=more_choices,pos=(300,722),style=wx.CB_READONLY)
            self.Bind(wx.EVT_COMBOBOX,self.addition,self.adding)
        def addition(self,event):
            if self.adding.GetValue()=='Home':
                print "1 ", self.ok
                for i in self.ok:
                    i.Destroy()
                self.ok = []
                self.ok.append(wx.StaticText(self.frame,-1,'Oranges',pos=(300,300)))
                print "2 ", self.ok
            elif self.adding.GetValue()=='Page One':
                print "3 ", self.ok
                for i in self.ok:
                    i.Destroy()
                self.ok = []
                self.ok.append(wx.StaticText(self.frame,-1,'Apples',pos=(300,300)))
                print "4 ", self.ok
            else: pass
    if __name__ =='__main__':
        app = wx.PySimpleApp()
        window = oranges(parent=None,id=-1)
        window.Show()
        app.MainLoop()
    

    【讨论】:

    • 信息量很大,我很高兴你花时间回答!
    【解决方案2】:

    正如@wnnmaw 已经熟练解释的那样,您的麻烦的原因是您仅部分地破坏了您的对象。

    我简化了你的代码:

    for i in ok:
        i.Destroy()
    

    到(编辑,最简单的方法曾经

    for _ in ok:
        el = ok.pop()
        el.Destroy()
    

    在一个操作组中销毁元素并将其从列表中弹出(删除)。

    【讨论】:

    • 我不确定我是否了解range(0,len(ok)) 发生的情况。你能解释一下吗?感谢您的回答!
    • 表达式只是遍历列表中的所有元素,而实际上没有将循环的结果分配给任何东西。你是对的,这比必要的复杂。请参阅编辑以了解最简单的方法。
    • @user3818089,实际上最好以原始方式进行。在迭代列表时从列表中删除元素是不好的做法,并且可能会出错。
    • @wnnmaw: [需要引用] SCNR
    猜你喜欢
    • 2019-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2018-10-18
    相关资源
    最近更新 更多