wxPython 在适合时崩溃

wxPython Crash on Fit

我正在尝试创建一个 wxPython 应用程序,它基于数据模型动态创建一些小部件和大小调整器,如下所示:

import wx

class FooWidget(wx.Panel):
    """ Displays information about an object in the data model. """
    def __init__(self, parent, idx):
        wx.Panel.__init__(self, parent)

        sizer = wx.BoxSizer(wx.VERTICAL)
        self.label = wx.StaticText(self, label=str(idx))
        sizer.Add(self.label)
        self.SetSizer(sizer)

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self,None)
        self.model = [0]

        self.button_sizer = wx.BoxSizer(wx.HORIZONTAL)
        add_button = wx.Button(self, label="add")
        add_button.Bind(wx.EVT_BUTTON, self.add)
        self.button_sizer.Add(add_button)

        self.rebuild()

    def add(self, evt):
        self.model.append(len(self.model))
        self.rebuild()
        print 'rebuild complete'

   def rebuild(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.button_sizer,1)

        widget_sizer = wx.BoxSizer(wx.HORIZONTAL)
        for idx in self.model:
            widget_sizer.Add(FooWidget(self, idx), 1)
        sizer.Add(widget_sizer,1)

        print 'SetSizer'
        self.SetSizer(sizer)
        print 'Fit'
        self.Fit()
        print 'Layout'
        self.Layout()

if __name__ == '__main__':
    app = wx.App(False)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()

应用程序启动良好,并在第一次成功执行了 rebuild() 方法。但是,在按下添加按钮后,我在控制台中看到以下内容:

SetSizer
Fit

然后应用程序挂了几秒钟,没有报告错误就崩溃了。我的真实数据模型比简单的 python 列表复杂一点,因此查询模型以了解应显示的内容比在视图中维护所有状态要容易得多。我该如何更改它以便我可以在应用程序不崩溃的情况下动态更改主要 window 的 sizer?

将 button_sizer 添加到新的父级 sizer 似乎会导致崩溃。尽管似乎没有合理的原因。

如果您编辑 class 以匹配以下内容,它会正常工作并按预期添加项目,不会出现崩溃:

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self,None)
        self.model = [0]

        self.add_button = wx.Button(self, label="add")
        self.add_button.Bind(wx.EVT_BUTTON, self.add)

        self.rebuild()

    def add(self, evt):
        self.model.append(len(self.model))
        self.rebuild()
        print 'rebuild complete'

    def rebuild(self):
        sizer = wx.BoxSizer(wx.VERTICAL)

        button_sizer = wx.BoxSizer(wx.HORIZONTAL)

        button_sizer.Add(self.add_button)

        sizer.Add(button_sizer,1)

        widget_sizer = wx.BoxSizer(wx.HORIZONTAL)
        for idx in self.model:
            widget_sizer.Add(FooWidget(self, idx), 1)
        sizer.Add(widget_sizer,1)

        print 'SetSizer'

        self.SetSizer(sizer)
        print 'Fit'
        self.Fit()

        print 'Layout'
        self.Layout()

希望对您的问题有所帮助。

迈克尔