Reputation: 4375
During a refactoring session, I put a lot of my gui code into little functions which directly inserts data into a wx.Sizer object.
For instance, this little function:
def buildStatusDisplay(self, status_disp, flag):
grid = wx.FlexGridSizer(cols=1, hgap=5, vgap=0)
font = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.LIGHT, False, 'Segoe UI')
for option in status_disp:
left = wx.StaticText(self, -1, option)
left.SetFont(font)
grid.Add(left, 0, flag=flag)
return grid
So it creates all of the StaticText objects using the throwaway left
, and then returns the FlexGrid
. However, I need some of the labels in the StaticText objects to update based on user input, but, I'm not sure how to access them.
I've looped through the sizer that gets returned from the function, but I don't see anything relating to a way that would let me get reference to the objects which make up the sizer.
for i in dir(sizer):
print i
>>Add
>>AddF
>>AddGrowableCol
>>AddGrowableRow
>>AddItem
>>AddMany
>>AddSizer
>>AddSpacer
>>AddStretchSpacer
>>AddWindow
>>CalcMin
>>CalcRowsCols
>>Children
>>ClassName
>>Clear
>>ColWidths
>>Cols
>>ComputeFittingCli
>>ComputeFittingWin
>>ContainingWindow
>>DeleteWindows
>>Destroy
>>Detach
>>Fit
>>FitInside
>>FlexibleDirection
>>GetChildren
>>GetClassName
>>GetColWidths
>>GetCols
>>GetContainingWind
>>GetFlexibleDirect
>>GetHGap
>>GetItem
>>GetItemIndex
>>GetMinSize
>>GetMinSizeTuple
>>GetNonFlexibleGro
>>GetPosition
>>GetPositionTuple
>>GetRowHeights
>>GetRows
>>GetSize
>>GetSizeTuple
>>GetVGap
>>HGap
>>Hide
>>Insert
>>InsertF
>>InsertItem
>>InsertSizer
>>InsertSpacer
>>InsertStretchSpac
>>InsertWindow
>>IsSameAs
>>IsShown
>>Layout
>>MinSize
>>NonFlexibleGrowMo
>>Position
>>Prepend
>>PrependF
>>PrependItem
>>PrependSizer
>>PrependSpacer
>>PrependStretchSpa
>>PrependWindow
>>RecalcSizes
>>Remove
>>RemoveGrowableCol
>>RemoveGrowableRow
>>RemovePos
>>RemoveSizer
>>RemoveWindow
>>Replace
>>RowHeights
>>Rows
>>SetCols
>>SetContainingWind
>>SetDimension
>>SetFlexibleDirect
>>SetHGap
>>SetItemMinSize
>>SetMinSize
>>SetNonFlexibleGro
>>SetRows
>>SetSizeHints
>>SetVGap
>>SetVirtualSizeHin
>>Show
>>ShowItems
>>Size
>>VGap
>>_ReplaceItem
>>_ReplaceSizer
>>_ReplaceWin
>>_SetItemMinSize
>>__class__
>>__del__
>>__delattr__
>>__dict__
>>__doc__
>>__format__
>>__getattribute__
>>__hash__
>>__init__
>>__module__
>>__new__
>>__reduce__
>>__reduce_ex__
>>__repr__
>>__setattr__
>>__sizeof__
>>__str__
>>__subclasshook__
>>__swig_destroy__
>>__weakref__
>>_setOORInfo
GetChildren()
returns only SizerItems
which don't seem to hold any reference to the underlying objects either.
Anyone know how to access something inside of a sizer? I suppose I could just explode the function a bit and either return a list of the objects as well as the sizer, or simple dump the function and keep identifiers to the objects I need to modify in main.. but... my gui code is already spaghetti enough. If I can avoid it, I would like to.
Upvotes: 2
Views: 3666
Reputation: 21
Probably already referenced in some other places, but could not find it so putting it here...
There is an additional way of doing this by using name
parameter during child creation i.e.:
left = wx.StaticText(self, -1, option, name='StaticTextChild')
Child then can be directly referenced/changed without the need for Sizer references.
staticTextChild = wx.FindWindowByName('StaticTextChild')
staticTextChild.SetLabel('new label:')
This method would probably not work directly in this example as you need to ensure unique child names to be able to access them. How you would do it is up to you.
Upvotes: 1
Reputation: 33071
I actually answered this kind of question a few months ago: wxPython: How to get sizer from wx.StaticText?
Basically, you just need to do something like this:
children = self.sizer.GetChildren()
for child in children:
widget = child.GetWindow()
print widget
if isinstance(widget, wx.TextCtrl):
widget.Clear()
In this case, you can see that I'm just checking for a wx.TextCtrl, but you can check for whatever widget you like. I also wrote an article on the subject on my blog.
Upvotes: 1
Reputation: 12138
On the wx.SizerItem
, there is a GetWindow
which gives you exactly that. Use IsWindow
to check if there is a 'window' available. All underlying objects inherit from wx.Window
, so that is what you want.
Here is an example, obj
is a wx.Frame
object:
>>> obj
<main.views.Main; proxy of <Swig Object of type 'wxFrame *' at 0x7fbaa1c70820> >
>>> obj.Sizer
<wx._core.BoxSizer; proxy of <Swig Object of type 'wxBoxSizer *' at 0x7fba9c9d48d0> >
>>> obj.Sizer.Children
wxSizerItemList: [<wx._core.SizerItem; proxy of <Swig Object of type 'wxSizerItem *' at 0x7fbaa1c21630> >, <wx._core.SizerItem; proxy of <Swig Object of type 'wxSizerItem *' at 0x7fbaa1c7faf0> >]
>>> obj.Sizer.Children[0]
<wx._core.SizerItem; proxy of <Swig Object of type 'wxSizerItem *' at 0x7fbaa1c21630> >
>>> obj.Sizer.Children[0].Window
<wx._windows.Panel; proxy of <Swig Object of type 'wxPanel *' at 0x7fba9c9d4d10> >
Upvotes: 2