如何在 wxPython 中删除 StaticBox?

问题描述

我有一个应用程序,我希望在其中删除 sizer 中的所有小部件。除了顽固地保留的 StaticBox 之外,这有效。我能做什么?它似乎不像一个 sizer,也不是一个普通的小部件。

import wx

class MainFrame(wx.Frame):
    def __init__(self,*args,**kwargs):
        super().__init__(None,**kwargs)

        self.panel = MainPanel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.panel)
        self.SetSizer(sizer)
        self.Center()
        self.Show()


class MainPanel(wx.Panel):
    def __init__(self,parent,**kwargs):
        super().__init__(parent,**kwargs)

        self.widget_sizer = self._widget_sizer()
        cmd_clear = wx.Button(self,id=wx.ID_CLEAR)
        cmd_clear.Bind(wx.EVT_BUTTON,self.clear_widgets)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.widget_sizer)
        sizer.Add(cmd_clear)
        self.SetSizer(sizer)

    def clear_widgets(self,event):
        self._delete_widgets(self.widget_sizer)

    def _widget_sizer(self):
        txt_test = wx.TextCtrl(self)

        test_Box = wx.StaticBox(parent=self,label="Box Label")
        test_sizer = wx.StaticBoxSizer(Box=test_Box,orient=wx.VERTICAL)
        chk_test = wx.CheckBox(self,label='Check test')
        test_sizer.Add(chk_test)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(txt_test)
        sizer.Add(test_sizer)
        return sizer

    def _delete_widgets(self,sizer):
        for child in sizer.GetChildren():
            if child.IsSizer():
                self._delete_widgets(child.GetSizer())
            else:
                child.Getwindow().Destroy()

if __name__ == '__main__':
        wx_app = wx.App()
        MainFrame()
        wx_app.MainLoop()

解决方法

我使用 wx.lib.inspection.InspectionTool 查看您的代码,似乎 staticBox 不是您的 sizer 的子项。

StaticBox 仍然存在,因为它的父级是您的 MainPanel

我尝试了不同的创建 StaticBox 的方法(包括让它由 BoxSizer 本身创建,然后使用 test_sizer.Add(test_sizer.GetStaticBox()) “手动”将它添加到 Sizer 但它不起作用:

wx._core.wxAssertionError: C++ assertion ""!m_containingSizer"" failed at /home/wxpy/wxPython-4.1.0/ext/wxWidgets/src/common/wincmn.cpp(2490) in SetContainingSizer(): Adding a window already in a sizer,detach it first!

BoxSizer 始终“附加”到 panel 的子代,并且永远不会是 SizerItem 的实例。

这有点奇怪......对我来说它看起来像是一个错误。它可能值 reporting it

我看到您删除它的唯一解决方法是使用以下方法单独访问它: panel.GetChildren() 并测试 child 是否为专有名称或 ID...