In wxPython, I am trying to adjust the border of items within a form on startup programatically in order to support higher DPI displays a bit better. I want to do is loop through each item in the frame (i.e. each row as shown in the editor) and double the "border" attribute if it has one. This mostly works great. However, some sizers I'm unable to find programmatically, specifically those which are nested inside other sizers.
I've recreated this on a simplified form:

I have set the border of each item to unique values so that I know which ones have been hit.
- panel1: border of 1
- hiddenSizer: border of 2
- bSizer261: border of 3
- bSizer27: border of 4
- bSizer28: border of 5
- bSizer29: border of 6
- m_staticText29: border of 7
My code to (attempt to) find all SizerItems is the following:
import wx
def walk_children(item):
for value in item.GetChildren():
yield value
for subvalue in walk_children(value):
yield subvalue
def adjust_border(frame : wx.Window):
for x in walk_children(frame):
print()
sizer = x.GetContainingSizer()
parents = [x]
while parents[-1].GetParent():
parents.append(parents[-1].GetParent())
print(x, sizer)
print(f"parents: {parents}")
if sizer:
for x in sizer.GetChildren():
print(x, x.GetBorder())
x.SetBorder(x.GetBorder() * 2)
class MainFrameBase ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"My Window", pos = wx.DefaultPosition, size = wx.Size( 318,359 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_WINDOW ) )
bSizer1 = wx.BoxSizer( wx.HORIZONTAL )
self.panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
bSizer23 = wx.BoxSizer( wx.VERTICAL )
hiddenSizer = wx.StaticBoxSizer( wx.StaticBox( self.panel1, wx.ID_ANY, u"Top Panel" ), wx.VERTICAL )
bSizer261 = wx.BoxSizer( wx.VERTICAL )
bSizer27 = wx.BoxSizer( wx.VERTICAL )
bSizer28 = wx.BoxSizer( wx.VERTICAL )
bSizer29 = wx.BoxSizer( wx.VERTICAL )
self.m_staticText29 = wx.StaticText( hiddenSizer.GetStaticBox(), wx.ID_ANY, u"MyLabel", wx.DefaultPosition, wx.DefaultSize, 0 )
self.m_staticText29.Wrap( -1 )
bSizer29.Add( self.m_staticText29, 0, wx.ALL, 7 )
bSizer28.Add( bSizer29, 1, wx.ALL|wx.EXPAND, 6 )
bSizer27.Add( bSizer28, 1, wx.ALL|wx.EXPAND, 5 )
bSizer261.Add( bSizer27, 1, wx.ALL|wx.EXPAND, 4 )
hiddenSizer.Add( bSizer261, 1, wx.ALL|wx.EXPAND, 3 )
bSizer23.Add( hiddenSizer, 1, wx.ALL|wx.EXPAND, 2 )
self.panel1.SetSizer( bSizer23 )
self.panel1.Layout()
bSizer23.Fit( self.panel1 )
bSizer1.Add( self.panel1, 1, wx.EXPAND |wx.ALL, 1 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
def __del__( self ):
pass
class MainFrame(MainFrameBase):
def __init__(self, parent):
# initialize
super().__init__(parent)
self.Layout()
adjust_border(self)
def run_gui():
# create the window
app = wx.App()
ex = MainFrame(None)
ex.Show()
app.MainLoop()
if __name__ == "__main__":
run_gui()
The output is this which indicates only 3/7 of them haved been found (those with borders of 1, 3, and 7:
<wx._core.Panel object at 0x00000133C3DD91F8> <wx._core.BoxSizer object at 0x00000133C3DD0DC8>
parents: [<wx._core.Panel object at 0x00000133C3DD91F8>, <__main__.MainFrame object at 0x00000133C3DD0D38>]
<wx._core.SizerItem object at 0x00000133C3FA2708> 1
<wx._core.StaticBox object at 0x00000133C3DD5E58> <wx._core.StaticBoxSizer object at 0x00000133C3DD5EE8>
parents: [<wx._core.StaticBox object at 0x00000133C3DD5E58>, <wx._core.Panel object at 0x00000133C3DD91F8>, <__main__.MainFrame object at 0x00000133C3DD0D38>]
<wx._core.SizerItem object at 0x00000133C3FA2708> 3
<wx._core.StaticText object at 0x00000133C3FA24C8> <wx._core.BoxSizer object at 0x00000133C3FA2438>
parents: [<wx._core.StaticText object at 0x00000133C3FA24C8>, <wx._core.StaticBox object at 0x00000133C3DD5E58>, <wx._core.Panel object at 0x00000133C3DD91F8>, <__main__.MainFrame object at 0x00000133C3DD0D38>]
<wx._core.SizerItem object at 0x00000133C3FA2708> 7
How do I loop through each SizerItem in a frame programmatically without skipping entries?
There are similar questions like this, but the answers do not provide nested SizerItems.
Generate List of All sizerItems Nested in wxPython Sizers