【发布时间】:2012-02-04 02:16:21
【问题描述】:
这是我一生的祸根:
Traceback(最近一次调用最后一次): OnDestroy 中的文件“C:\Users\User\Documents\PYTHON\GAME FILES\simple.py”,第 18 行 自我毁灭() 文件“C:\Python26\lib\site-packages\wx-2.8-msw-ansi\wx_core.py”,第 14610 行,在 getattr_ 中 引发 PyDeadObjectError(self.attrStr % self._name) wx._core.PyDeadObjectError: MyPanels 对象的 C++ 部分已被删除,属性 > 不再允许访问。
我的目标:拥有两个面板,左侧面板杀死并通过按钮“重新创建”右侧面板/相同的副本,模拟用户如何在左侧面板中选择他们想要查看的内容和让右侧面板显示此内容。这就是我在更复杂的程序中尝试做的事情,但是失败了,所以我想在这里学习如何破坏和重新创建一个空白面板。仍然是同样可怕的错误。
代码:
import wx
import sys
import traceback
def show_error():
message = ''.join(traceback.format_exception(*sys.exc_info()))
dialog = wx.MessageDialog(None, message, 'Error!', wx.OK|wx.ICON_ERROR)
dialog.ShowModal()
class MyPanels(wx.Panel):
def __init__(self, parent, id):
wx.Panel.__init__(self, parent)
self.parent = parent
def OnDestroy(self, event):
self.Destroy()
def OnTest(self, event):
print "Hello"
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(1000, 480))
self.parent = parent
self.panel = MyPanels(self, -1)
self.panel.SetBackgroundColour("grey")
self.panel.leftpanel = MyPanels(self.panel, 1)
self.panel.rightpanel = MyPanels(self.panel, 1)
self.panel.leftpanel.SetBackgroundColour("red")
self.panel.rightpanel.SetBackgroundColour("green")
self.panel.basicsizer = wx.BoxSizer(wx.HORIZONTAL)
self.panel.basicsizer.Add(self.panel.leftpanel, 1, wx.EXPAND)
self.panel.basicsizer.Add(self.panel.rightpanel, 1, wx.EXPAND)
self.panel.SetSizer(self.panel.basicsizer)
button = wx.Button(self.panel.leftpanel, 1, 'DIE DIE DIE', (50, 130))
buttonres = wx.Button(self.panel.leftpanel, 2, 'Resurrect', (50, 230))
buttonextra = wx.Button(self.panel.leftpanel, 3, 'Test', (50, 330))
self.Bind(wx.EVT_BUTTON, self.panel.rightpanel.OnDestroy, id = 1)
self.Bind(wx.EVT_BUTTON, self.CreateNewPanel, id = 2)
self.Bind(wx.EVT_BUTTON, self.panel.rightpanel.OnTest, id = 3)
def CreateNewPanel(self, event):
self.panel.rightpanel = MyPanels(self.panel, 1)
self.panel.rightpanel.SetBackgroundColour("green")
self.panel.basicsizer.Add(self.panel.rightpanel, 1, wx.EXPAND)
self.panel.SetSizer(self.panel.basicsizer)
self.panel.rightpanel.Refresh()
self.panel.leftpanel.Refresh()
self.panel.leftpanel.Layout()
self.panel.leftpanel.Update()
self.panel.Layout()
self.Update()
self.Show(True)
self.Centre()
def main():
app = wx.App()
try:
frame = MyFrame(None, -1, 'Die.py')
frame.Show()
app.MainLoop()
except:
show_error()
if __name__ == '__main__':
main()
基本上,我似乎(终于)让复活按钮工作了,至少在“新”面板填充了适当的空间方面。但如果我再次尝试杀死它,就会出现可怕的错误。
我一直在研究错误消息,似乎我得到了这个,因为 self.Destroy() 破坏了程序中某些东西仍然需要的东西。我发现这很难理解,因为我认为我正在创建一个完全相同的副本,直到相同的名称。
我认为唯一可以是“杀死”按钮本身。就好像它需要原来的右面板再次销毁,它被锁定在其唯一的类引用中,而不是它的右面板名称。我添加了第三个按钮来测试它。第三个按钮的代码几乎相同,只是调用了 MyPanels 类中的不同方法。而且......它在杀戮和复活之后仍然有效。但是再按Kill 就不行了。它们之间的唯一区别是 OnDestroy 方法使用“self”。
不知何故,我想我必须停止将 Kill 按钮的事件绑定到原始右侧面板的“自我”。我完全迷失了。我已经绝望地尝试告诉左侧面板刷新/更新自身。没有。过去两天一直在努力解决这个问题。我是 python 和 wxpython 的新手,在这里完全不知所措,但请帮帮我。
已编辑-
好的,刚才有一个迷你脑电波。我认为一旦事件与 Bind 命令绑定,它将永远绑定到该小部件,除非它被更改。这就是为什么它仍然坚持死板。 所以如果我解绑然后重新绑定,这样就解决了吗?
我已将按钮名称更改为 self.button。然后在 def CreateNewPanel() 方法中,我将 Unbind 命令放入...然后立即将复制粘贴的 Bind 命令放入其中。它现在似乎工作了!!!!
但是……谁能告诉我: 1)这是正确的解决方案还是我想出的一些麻烦的解决方法 和 2)为什么当我打电话时,为什么整个画面会在我的屏幕上跳半英寸 self.panel.rightpanel.Refresh()?
** 编辑 -
现在我似乎能够根据 LeftPanel 的按钮销毁和重新创建 RightPanel,我已尝试在复杂程序上进行管理。 该复杂程序旨在根据用户在 LeftPanel 上选择名称的 listctrl 来在 RightPanel 中显示角色的信息(bio + pic)。
所以它与此非常相似:它不是有一个空的 RightPanel,而是有大量的小部件。
它确实有效......在一定程度上。如果我单击查看角色 X,RightPanel 会自行销毁,然后使用角色 Y 的小部件重新创建自己。耶。但它也会暂时在 RightPanel 的左上角闪烁一个小方块,其中清楚地包含所有小部件的副本。
该方块几乎立即消失,但每次单击更改 RightPanel 的内容时都清晰可见。这很丑陋。我就是无法摆脱它!我已经尝试在 .Layout() 各处和所有内容中打点,不。无法弄清楚为什么它会出现然后消失!是我无法摆脱的程序延迟吗?或者我在使用我的尺码器时犯了一些错误?必须强调 - 小部件按我的意图完美布置......所以尺寸器肯定工作正常......对吗? **
【问题讨论】:
标签: wxpython