Zack
Zack

Reputation: 4375

wxpython: How do you access the objects which you've placed inside of a wx.Sizer object?

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

Answers (3)

Kwisatz Haderach
Kwisatz Haderach

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

Mike Driscoll
Mike Driscoll

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

Bouke
Bouke

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

Related Questions