在wxPython中切换帧时出现wx._core.PyDeadObjectError?
我在使用 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()
提前谢谢大家,我很期待看到你们的回答!
2 个回答
1
正如@wnnmaw已经很清楚地解释过的,你遇到的问题是因为你只部分地销毁了你的对象。
我简化了你的代码:
for i in ok:
i.Destroy()
变成了(编辑,最简单的方法就是这样)
for _ in ok:
el = ok.pop()
el.Destroy()
在一个操作中同时销毁这个元素并把它从列表中移除。
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()