Sizer error

Help
2011-01-09
2013-05-01
  • i'm getting an error when using the following code:

    self.h_sizer = wx.StaticBoxSizer(wx.HORIZONTAL)
            self.staticBoxNavigate = wx.StaticBox(self,label="Navigate")
            self.h_sizer.Add(self.staticBoxNavigate,0)
            self.SetSizer(self.h_sizer)
    

    here's the error:

    AttributeError: h_sizer

    i've copied the code from an example.

    thanks for any help,
    bob k.

     
  • Chelonian
    Chelonian
    2011-01-10

    Did you copy and paste your code into this message and also copy and paste the full error?  I would think that if it says AttributeError and just h_sizer, there is a place in your code where you use h_sizer instead of self.h_sizer.

     
  • No i did not copy and paste, but the above code is where i have h_sizer.  Here's a copy of the error window:

    Traceback (most recent call last):
      File "C:\Photography\Software\boa\FrameMain.py", line 76, in OnMenuEditTablesEditchemicaltableMenu
        dlg = DialogChemicalTable.DialogChemicalTable(self)
      File "C:\Photography\Software\boa\DialogChemicalTable.py", line 29, in __init__
        self._init_ctrls(parent)
      File "C:\Photography\Software\boa\DialogChemicalTable.py", line 22, in _init_ctrls
        self.staticBoxSizerNavigate = wx.StaticBoxSizer(wx.HORIZONTAL)
      File "C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 13293, in __init__
        _core_.StaticBoxSizer_swiginit(self,_core_.new_StaticBoxSizer(*args, **kwargs))
    TypeError: in method 'new_StaticBoxSizer', expected argument 1 of type 'wxStaticBox *'

     
  • Bob,

    This is not the traceback of you AttributeError: 'h_sizer'

    Here you have a problem on line 22 of DialogChemicalTable.py:
    self.staticBoxSizerNavigate = wx.StaticBoxSizer(wx.HORIZONTAL)

    It should be:
    self.staticBoxSizerNavigate = wx.StaticBoxSizer(instancename of your staticbox, wx.HORIZONTAL)

    Whenever you get a Traceback you should start looking at the lines given from the bottom up.  In the above the error is caught on lin 13293 in _core.py, this is not in your code, so assume the error is not here, go up a line and you are in your code and there is a problem with that line.

    Your AttributeError problem can be resolved in the same way, look at the traceback and "walk up the stack trace" shown by it until you see the error.   I get this error quit often as I often misspell things, or it cauld also happen that you missed out "self" or that self._h_sizer is only defined later on in your code, in which case move its definition higher up or move the code causing the problem to after its creation.

    Whenever you report a traceback here or on any other list, give the full traceback (even if it is long) as that is the minimum needed to help you.  It is often also helpful to show the lines just around the error within your code.  If that shows that the error is not in your code people can pin point other possible causes or if that is no possible then it often helps to do "http://wiki.wxpython.org/MakingSampleApps", I don't know how often I found my error trying to make a sample application to show the problem in isolation.

    Hope this helps

    Werner

     
  • Here's the new code:

    #Boa:Dialog:DialogChemicalTable
    import wx
    import ObjectListView
    def create(parent):
        return DialogChemicalTable(parent)
    [wxID_DIALOGCHEMICALTABLE, wxID_DIALOGCHEMICALTABLESTATICBOXNAVIGATE, 
    ] = [wx.NewId() for _init_ctrls in range(2)]
    class DialogChemicalTable(wx.Dialog):
        
        def _init_ctrls(self, prnt):
            # generated method, don't edit
            wx.Dialog.__init__(self, id=wxID_DIALOGCHEMICALTABLE,
                  name='DialogChemicalTable', parent=prnt, pos=wx.Point(780, 336),
                  size=wx.Size(598, 411), style=wx.DEFAULT_DIALOG_STYLE,
                  title='Edit Chemical Table')
            self.SetClientSize(wx.Size(582, 373))
            self.staticBoxNavigate = wx.StaticBox(id=wxID_DIALOGCHEMICALTABLESTATICBOXNAVIGATE,
                  label=u'Navigate', name=u'staticBoxNavigate', parent=self,
                  pos=wx.Point(216, 144), size=wx.Size(200, 100), style=0)
                  
            self.h_sizer = wx.StaticBoxSizer(self.staticBoxNavigate,wx.HORIZONTAL)
            self.SetSizer(self.h_sizer)
        def __init__(self, parent):
            self._init_ctrls(parent)
    

    Here's the traceback:

    10:29:44 AM: Traceback (most recent call last):
    10:29:44 AM:   File "c:\Python27\Lib\site-packages\boa-constructor\Models\wxPythonControllers.py", line 78, in OnDesigner     self.showDesigner()
    10:29:44 AM:   File "c:\Python27\Lib\site-packages\boa-constructor\Models\wxPythonControllers.py", line 143, in showDesigner     designer.refreshCtrl()
    10:29:44 AM:   File "c:\Python27\Lib\site-packages\boa-constructor\Views\Designer.py", line 395, in refreshCtrl     self.initObjProps(objCol.propertiesByName, '', objCol.creators, deps, depLnks)
    10:29:44 AM:   File "c:\Python27\Lib\site-packages\boa-constructor\Views\InspectableViews.py", line 197, in initObjProps     {'self': self.controllerView.objectNamespace})
    10:29:44 AM:   File "c:\Python27\Lib\site-packages\boa-constructor\PaletteMapping.py", line 158, in evalCtrl     return eval(expr, globals(), localsDct)
    10:29:44 AM:   File "<string>", line 1, in <module>
    10:29:44 AM:   File "c:\Python27\Lib\site-packages\boa-constructor\Views\Designer.py", line 1534, in __getattr__     raise AttributeError, name
    10:29:44 AM: AttributeError: h_sizer

    To give you a little background, i tried this from the Boa Toolbar originally.  I added a staticBox.  I then added a staticBoxSizer.  There was a create sizer window, and it defaulted to the staticBox i instantiated.  I double clicked the staticBoxSizer, and added a new item.  in the Window property i selected the staticBox.  The cursor changed to a spinning wheel and eventually the Boa Constructor shut down.

    I have been trying many different ways to get a sizer and staticbox on my wx.Dialog

    bob k.

     
  • Hi Bob,

    I am just guessing, you are probably crashing because the staticBox is already asigned to a sizer when you add the staticBoxSizer.

    Following is the code for a dialog with just a static box and I did the following steps to create it.
    - create dialog
    - menu Edit/add module runneer
    - add a wx.StaticBox
    - add a wx.StaticBoxSizer and select the previously created SB
    - rename the StaticBoxSizer and post/save it all

    You are getting the h_sizer attribute error as the def _init_sizers is missing in your code.

    #Boa:Dialog:Dialog1

    import wx

    def create(parent):
        return Dialog1(parent)

    [wxID_DIALOG1, wxID_DIALOG1STATICBOX1,
    ] =

    class Dialog1(wx.Dialog):
        def _init_sizers(self):
            # generated method, don't edit
            self.sBoxSizer = wx.StaticBoxSizer(box=self.staticBox1,
                  orient=wx.VERTICAL)

            self.SetSizer(self.sBoxSizer)

        def _init_ctrls(self, prnt):
            # generated method, don't edit
            wx.Dialog.__init__(self, id=wxID_DIALOG1, name='', parent=prnt,
                  pos=wx.Point(696, 290), size=wx.Size(225, 206),
                  style=wx.DEFAULT_DIALOG_STYLE, title='Dialog1')
            self.SetClientSize(wx.Size(209, 168))

            self.staticBox1 = wx.StaticBox(id=wxID_DIALOG1STATICBOX1,
                  label='staticBox1', name='staticBox1', parent=self,
                  pos=wx.Point(0, 0), size=wx.Size(209, 168), style=0)

            self._init_sizers()

        def __init__(self, parent):
            self._init_ctrls(parent)

    if __name__ == '__main__':
        app = wx.PySimpleApp()
        dlg = create(None)
        try:
            dlg.ShowModal()
        finally:
            dlg.Destroy()
        app.MainLoop()

     
  • Just to understand, the following code would no longer work:

    def create_controls(self):
        """Called when the controls on Window are to be created"""
        # Horizontal sizer
        self.h_sizer = wx.BoxSizer(wx.HORIZONTAL)
        # Create the static text widget and set the text
        self.text = wx.StaticText(self, label="Enter some text:")
        #Create the Edit Field (or TextCtrl)
        self.edit = wx.TextCtrl(self, size=wx.Size(250, -1))
        #Add to horizontal sizer
        #add the static text to the sizer, tell it not to resize
        self.h_sizer.Add(self.text, 0,)
        #Add 5 pixels between the static text and the edit
        self.h_sizer.AddSpacer((5,0))
        #Add Edit
        self.h_sizer.Add(self.edit, 1)
        #Set the sizer
        self.SetSizer(self.h_sizer)
    
     
  • Hi Bob,

    I assume you want to add a StaticText and TextCtrl to the staticBox, is this correct?

    - to my previous example add a FlexGridSizer (just my preference, you could use a BoxSizer)
    - add a StaticText and a TextCtrl and make sure there are in the FlexGridSizer or add them manually to it.

    #Boa:Dialog:Dialog1

    import wx

    def create(parent):
        return Dialog1(parent)

    [wxID_DIALOG1, wxID_DIALOG1STATICBOX1, wxID_DIALOG1STATICTEXT1,
    wxID_DIALOG1TEXTCTRL1,
    ] =

    class Dialog1(wx.Dialog):
        def _init_coll_fgsInsideStaticBox_Growables(self, parent):
            # generated method, don't edit

            parent.AddGrowableCol(1)

        def _init_coll_sBoxSizer_Items(self, parent):
            # generated method, don't edit

            parent.AddSizer(self.fgsInsideStaticBox, 1, border=0, flag=wx.EXPAND)

        def _init_coll_fgsInsideStaticBox_Items(self, parent):
            # generated method, don't edit

            parent.AddWindow(self.staticText1, 0, border=0, flag=0)
            parent.AddWindow(self.textCtrl1, 0, border=0, flag=wx.EXPAND)

        def _init_sizers(self):
            # generated method, don't edit
            self.sBoxSizer = wx.StaticBoxSizer(box=self.staticBox1,
                  orient=wx.VERTICAL)

            self.fgsInsideStaticBox = wx.FlexGridSizer(cols=2, hgap=0, rows=0,
                  vgap=0)

            self._init_coll_sBoxSizer_Items(self.sBoxSizer)
            self._init_coll_fgsInsideStaticBox_Items(self.fgsInsideStaticBox)
            self._init_coll_fgsInsideStaticBox_Growables(self.fgsInsideStaticBox)

            self.SetSizer(self.sBoxSizer)

        def _init_ctrls(self, prnt):
            # generated method, don't edit
            wx.Dialog.__init__(self, id=wxID_DIALOG1, name='', parent=prnt,
                  pos=wx.Point(846, 300), size=wx.Size(334, 111),
                  style=wx.DEFAULT_DIALOG_STYLE, title='Dialog1')
            self.SetClientSize(wx.Size(318, 73))

            self.staticBox1 = wx.StaticBox(id=wxID_DIALOG1STATICBOX1,
                  label='staticBox1', name='staticBox1', parent=self,
                  pos=wx.Point(0, 0), size=wx.Size(318, 73), style=0)

            self.staticText1 = wx.StaticText(id=wxID_DIALOG1STATICTEXT1,
                  label='staticText1', name='staticText1', parent=self,
                  pos=wx.Point(5, 17), size=wx.Size(55, 13), style=0)

            self.textCtrl1 = wx.TextCtrl(id=wxID_DIALOG1TEXTCTRL1, name='textCtrl1',
                  parent=self, pos=wx.Point(60, 17), size=wx.Size(100, 21), style=0,
                  value='textCtrl1')

            self._init_sizers()

        def __init__(self, parent):
            self._init_ctrls(parent)

    if __name__ == '__main__':
        app = wx.PySimpleApp()
        dlg = create(None)
        try:
            dlg.ShowModal()
        finally:
            dlg.Destroy()
        app.MainLoop()

    Or you could have added your code in the previous post like this:
    #Boa:Dialog:Dialog1

    import wx

    def create(parent):
        return Dialog1(parent)

    [wxID_DIALOG1, wxID_DIALOG1STATICBOX1,
    ] =

    class Dialog1(wx.Dialog):

        def _init_sizers(self):
            # generated method, don't edit
            self.sBoxSizer = wx.StaticBoxSizer(box=self.staticBox1,
                  orient=wx.VERTICAL)

            self.fgsInsideStaticBox = wx.FlexGridSizer(cols=2, hgap=0, rows=0,
                  vgap=0)

            self.SetSizer(self.sBoxSizer)

        def _init_ctrls(self, prnt):
            # generated method, don't edit
            wx.Dialog.__init__(self, id=wxID_DIALOG1, name='', parent=prnt,
                  pos=wx.Point(846, 300), size=wx.Size(334, 111),
                  style=wx.DEFAULT_DIALOG_STYLE, title='Dialog1')
            self.SetClientSize(wx.Size(318, 73))

            self.staticBox1 = wx.StaticBox(id=wxID_DIALOG1STATICBOX1,
                  label='staticBox1', name='staticBox1', parent=self,
                  pos=wx.Point(0, 0), size=wx.Size(318, 73), style=0)

            self._init_sizers()

        def __init__(self, parent):
            self._init_ctrls(parent)
            self.create_controls()

        def create_controls(self):
        """Called when the controls on Window are to be created"""
        # Horizontal sizer
        self.h_sizer = wx.BoxSizer(wx.HORIZONTAL)
       
        # Create the static text widget and set the text
        self.text = wx.StaticText(self, label="Enter some text:")
        #Create the Edit Field (or TextCtrl)
        self.edit = wx.TextCtrl(self, size=wx.Size(250, -1))
       
        #Add to horizontal sizer
        #add the static text to the sizer, tell it not to resize
        self.h_sizer.Add(self.text, 0)
        #Add 5 pixels between the static text and the edit
        self.h_sizer.AddSpacer((5,0))
        #Add Edit
        self.h_sizer.Add(self.edit, 0, wx.EXPAND)
       
            ##    #Set the sizer
            ##    self.SetSizer(self.h_sizer)
            # instead add to the existing sizer
            mainSizer = self.GetSizer()
            mainSizer.AddSizer(self.h_sizer, 1, border=0, flag=wx.EXPAND)
            mainSizer.Layout()

    if __name__ == '__main__':
        app = wx.PySimpleApp()
        dlg = create(None)
        try:
            dlg.ShowModal()
        finally:
            dlg.Destroy()
        app.MainLoop()

     
  • uhhh, i'm hopeless…

    let me explain what i'm trying to do.  at the bottom of the dialog i want to have a navigate pane with up and down arrows (buttons), a command pane with save cancel and exit (buttons). i want both of these panes anchored to the bottom of the frame no matter how it's sized.  above these two panes i'm going to have the objectlistgrid.   i'm trying to mimic the Demo.py you sent me.  you seemed to have a panel, a staticbox, a staticboxsizer and some buttons.  some of my confusion is that the Demo.py has code similar to:

    self.sizer_9_staticbox = wx.StaticBox(self.notebook_1_pane_6,-1,"print commands")

    the code i'm seeing now has id=…, label=…, size=…  

    and i'm having difficulty how one relates to the other. my apologies for this.  i'm sure once i get a handle on this i won't bother you every again… :)

    bob k.
    bob k.

     
  • Bob,

    Demo.py?  The wxPython demo, yes?

    self.sizer_9_staticbox = wx.StaticBox(self.notebook_1_pane_6,-1,"print commands")

    is equal to:
    self.sizer_9_staticbox = wx.StaticBox(self.notebook_1_pane_6, id=-1, label="print commands")

    Code generated by Boa always uses the second version as it is clearer, more future proof but it means you have to type more.

    The following would be invalid:
    self.sizer_9_staticbox = wx.StaticBox(self.notebook_1_pane_6, "print commands", -1)

    Where this would still be valid:
    self.sizer_9_staticbox = wx.StaticBox(self.notebook_1_pane_6, label="print commands", id=-1)

    The later uses keyword arguments where the first one uses positional arguments.

    This is standard Python stuff, so you might want to read up in e.g.:

    http://diveintopython.org/power_of_introspection/optional_arguments.html

    or get some books:
    - Learning Python by Mark Lutz & David Asher is pretty good
    - wxPython in Action by Rappin and Robin Dunn (wxPython's god:) )
    - wxPython 2.8 Application Development Cookbook by Cody Precord

    I can recommend all three, just got the last one a couple of weeks ago (as a little financial contribution to the wxPython project and I was hoping to learn a few more tricks - which I did, haven't finished reading it, so will probably learn some more).

    Werner

     
  • thank  you Werner.