dale
dale

Reputation: 65

What is best way to find the "parent" sizer in nested sizers?

In wxpython I have a GridBagSizer, gs, with some nested sizers s1 and s2 and a button b, in a single cell.

On an EVT_BUTTON event I get the button object. To move the button object around in the grid, to a different grid cell, I need to move the top level sizer, s1, which is the direct "child" (if that's the correct term) of the GridBagSizer, gs. What is the best way to find the top-level sizer?

object.GetContainingSizer() returns the button object's sizer, s2, but I can't see how to get to s1. Do I need to store the reference to s1 in my s2 (or b) object? This seems rather inelegant?

# pseudocode
panel=wx.Panel( None )
gs= wx.GridBagSizer()
s1= wx.BoxSizer()
s2= wx.BoxSizer()
b= wx.Button(panel, wx.ID_ANY, 'AButton')

s2.Add( b )
s1.Add( s2 )
gs.Add( s1, (row,col))

Answer (so far): I found a piece of code for which I don't know who to credit - seems to have something to do with dabo. It's in dGridSizer.py, but it did a similar thing I'm looking for:

szitm= grid_sizer.FindItemAtPosition( (row,col) )
if szitm:
    if szitm.IsWindow():
        itm=szitm.GetWindow()
    elif szitm.IsSizer():
        itm=szitm.GetSizer()
    try: # in case some other IsSomething() I don't have covered
        grid_sizer.SetItemPosition( itm, (newrow,col))
    except:
        pass

That seems to work in all the cases I have in my grid so far. Not sure I understand it at this point, I'll have to dig into the code later - now just have to make this work.

Upvotes: 1

Views: 2311

Answers (2)

RobinDunn
RobinDunn

Reputation: 6206

A trick I've done sometimes is to take one of the widgets managed by the sizer I'm working with, get its parent, and then get the parent's sizer. Unless you're doing something really weird that should be the top-level parent sizer of the sizer you're working with (or the sizer itself if it is the one at the top of that hierarchy.

parentSizer = widget.GetParent().GetSizer()

Upvotes: 6

Mike Driscoll
Mike Driscoll

Reputation: 33071

No, you don't need to store a reference in the sizer, but you do have to store a reference to the sizer. Make your sizer definitions like this:

self.gs = wx.GridBagSizer()
self.s1 = wx.BoxSizer()
self.s2 = wx.BoxSizer()

Then you can access the sizers elsewhere in your application and Add or Remove widgets as needed.

Upvotes: 0

Related Questions