[wxPython] sizers with wxStaticBox vs wxWindow

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[wxPython] sizers with wxStaticBox vs wxWindow

Gary Bankston
I working on a way to build compound widgets. Sometimes I want just want
the bare widget with no 'border', sometimes I want a widget that has a
'border' or 'frame' and a title on it (similar to wxRadioBox). These
widgets will need to be resizable, so they will need a sizer.

My basic approach is to subclass either a wxWindow or a wxStaticBox then
add a wxBoxSizer. The widgets that use wxWindow work fine, but the ones
that use wxStaticBox don't work right.

With wxStaticBox the window look right when it first opens up, but when
you resize it some of the subwindows get postioned wrong. Its as if they
are not properly connected to the sizers or something.

I've worked on this for some time and I'm stumped. I would have thought
that a wxStaticBox would work the same as a wxWindow sinee it is a
superclass of a wxWindow. Apparantly not.

Here's my test code
-----------------------------------------------------------------------------

from wxPython.wx import *

#
# classes that subclass WindowSizer work
#
class WindowSizer( wxWindow ):
 # Edits a dictlist
 def __init__( self, parent, ID, orientation, intborder=0,
        *va, **kw ):

  # init ----------------------------------
  va = (self, parent, ID) + va
  apply( wxWindow.__init__, va, kw )

  # Sizer
  self.sizer = wxBoxSizer( orientation )

  # configure ------------------------------
  self.SetAutoLayout( TRUE )
  self.SetSizer( self.sizer )

  # super classes need this at the end of __init__
  # self.sizer.Fit( self )

 def OnSize( self, event ):
  self.Layout()
#
# classes that subclass StaticBoxSizer do not work
#
class StaticBoxSizer( wxStaticBox ):
 # Edits a dictlist
 def __init__( self, parent, ID, label, orientation, intborder=0,
        *va, **kw ):

  # init ----------------------------------
  va = (self, parent, ID, label) + va
  apply( wxStaticBox.__init__, va, kw )

  # Sizer ------------------------------
  self.sizer = wxStaticBoxSizer( self, orientation )

  # configure ------------------------------
  EVT_SIZE( self, self.OnSize )
  self.SetAutoLayout( TRUE )
  self.SetSizer( self.sizer )

  # super classes need this at the end of __init__
  # self.sizer.Fit( self )

 def OnSize( self, event ):
  self.Layout()

class TestWindow( WindowSizer ):
 def __init__( self, parent, ID, orientation, color,
        *va, **kw ):
  va = ( self, parent, ID, orientation, 10 ) + va
  apply( WindowSizer.__init__, va, kw )

  window = wxWindow( self, -1 )
  self.sizer.Add( window, 1, wxEXPAND )
  window.SetBackgroundColour( color )

  self.sizer.Fit( self )
  self.SetSize( wxSize( 250, 300 ) )

class CompoundTestWindow( WindowSizer ):
 def __init__( self, parent, ID, orientation, colora, colorb,
        *va, **kw ):
  va = ( self, parent, ID, orientation, 10 ) + va
  apply( WindowSizer.__init__, va, kw )

  windowa = wxWindow( self, -1 )
  self.sizer.Add( windowa, 1, wxEXPAND )
  windowa.SetBackgroundColour( colora )

  windowb = TestWindow( self, -1, wxVERTICAL, colorb )
  self.sizer.Add( windowb, 1, wxEXPAND )

  self.sizer.Fit( self )

class TestBox( StaticBoxSizer ):
 def __init__( self, parent, ID, label, orientation, color,
        *va, **kw ):
  va = ( self, parent, ID, label, orientation, 10 ) + va
  apply( StaticBoxSizer.__init__, va, kw )

  window = wxWindow( self, -1 )
  self.sizer.Add( window, 1, wxEXPAND )
  window.SetBackgroundColour( color )

  self.sizer.Fit( self )
  self.SetSize( wxSize( 250, 300 ) )

class CompoundTestBox( StaticBoxSizer ):
 def __init__( self, parent, ID, labela, labelb, orientation, colora,
colorb,
        *va, **kw ):
  va = ( self, parent, ID, labela, orientation, 10 ) + va
  apply( StaticBoxSizer.__init__, va, kw )

  windowa = wxWindow( self, -1 )
  self.sizer.Add( windowa, 1, wxEXPAND )
  windowa.SetBackgroundColour( colora )

  windowb = TestBox( self, -1, labelb, wxVERTICAL, colorb )
  self.sizer.Add( windowb, 1, wxEXPAND )

  self.sizer.Fit( self )

class TestFrame( wxFrame ):
 def __init__( self, parent, ID ):
  wxFrame.__init__( self, parent, ID, "Static Box Test Frame" )
  topsizer = wxBoxSizer( wxHORIZONTAL )

  # sizeres
  leftsizer = wxBoxSizer( wxVERTICAL )
  topsizer.Add( leftsizer, 1, wxEXPAND | wxALL, 10 )
  rightsizer = wxBoxSizer( wxVERTICAL )
  topsizer.Add( rightsizer, 1, wxEXPAND | wxALL, 10 )

  # test windows
  # these all work correctly
##  bluebox = TestWindow( self, -1, wxVERTICAL, wxBLUE )
##  redbox = TestWindow( self, -1, wxVERTICAL, wxRED )
##  greenbox = TestWindow( self, -1, wxVERTICAL, wxGREEN )
##  greenbox = CompoundTestWindow( self, -1, wxVERTICAL, wxGREEN,
##                  wxNamedColour( 'MEDIUM AQUAMARINE') )

  # test static boxes
  # these 2 work
  bluebox = TestBox( self, -1, 'Blue Box', wxVERTICAL, wxBLUE )
  redbox = TestBox( self, -1, 'Red Box', wxVERTICAL, wxRED )
  # both versions of this one fail
  greenbox = TestBox( self, -1, 'Green Box', wxVERTICAL, wxGREEN )
##  greenbox = CompoundTestBox( self, -1, 'Green Box', 'Inner Box',
##                  wxVERTICAL, wxGREEN,
##                  wxNamedColour( 'MEDIUM AQUAMARINE') )

  leftsizer.Add( bluebox, 1, wxEXPAND )
  leftsizer.Add( redbox, 1, wxEXPAND )
  rightsizer.Add( greenbox, 1, wxEXPAND )

  # configure
  self.SetAutoLayout( TRUE ) # tell frame to use sizer
  self.SetSizer( topsizer )
  topsizer.Fit( self )

class MyApp(wxApp):
 def __init__( self  ):
  wxApp.__init__( self )

 def OnInit(self):
  self.frame = TestFrame( NULL, -1 )
  self.frame.Show( true )
  self.SetTopWindow( self.frame )
  return true

# create a dialog box for creating/editing net classes
app = MyApp(  )
app.MainLoop()



--
  __^__
/_______\  glary
\_______/  sandstorm
   /|\



_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] sizers with wxStaticBox vs wxWindow

Robin Dunn
> I working on a way to build compound widgets. Sometimes I want just want
> the bare widget with no 'border', sometimes I want a widget that has a
> 'border' or 'frame' and a title on it (similar to wxRadioBox). These
> widgets will need to be resizable, so they will need a sizer.
>
> My basic approach is to subclass either a wxWindow or a wxStaticBox then
> add a wxBoxSizer. The widgets that use wxWindow work fine, but the ones
> that use wxStaticBox don't work right.
>
> With wxStaticBox the window look right when it first opens up, but when
> you resize it some of the subwindows get postioned wrong. Its as if they
> are not properly connected to the sizers or something.
>
> I've worked on this for some time and I'm stumped. I would have thought
> that a wxStaticBox would work the same as a wxWindow sinee it is a
> superclass of a wxWindow. Apparantly not.
>

Well, sort of.  The wxStaticBox class is a sub-class of wxWindow, but it
really just wraps the static box control from microsoft.  The wxWindow
methods send messages to the box just like any other window, but there's no
telling what the control actually does with the messages...

On wxGTK it is even worse.  Some of the controls in GTK don't use a widget
(window) but just draw themselves on the parent window, so things that you
expect to be able to do, like setting the background colour, are just
ignored.

You may be better off to still use a wxWindow as the base and just place a
wxStaticBox on it.  Maybe a flag given to your WindowSizer determine whether
or not it creates a wxStaticBox and wxStaticBoxSizer or just a wxBoxSizer.
You wouldn't even need another class that way.

--
Robin Dunn
Software Craftsman
[hidden email]
http://AllDunn.com/robin/
http://AllDunn.com/wxPython/  Check it out!




_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users



Reply | Threaded
Open this post in threaded view
|

Re: [wxPython] sizers with wxStaticBox vs wxWindow

Gary Bankston
> You may be better off to still use a wxWindow as the base and just place a
> wxStaticBox on it.  Maybe a flag given to your WindowSizer determine whether
> or not it creates a wxStaticBox and wxStaticBoxSizer or just a wxBoxSizer.
> You wouldn't even need another class that way.

humm, interesting. That's the way I started, but decided to change after I found

that trying to change the widgets background color with
goop.SetBackgroundColour() didn't work. Actually it did work but since the
wxWindow was covered with a wxStaticBox the color change could not be seen.

If I just place a wxStaticBox on a window it seems like I will have to add
wrapper methods to call the SetBackgroundColour method of the staticbox instead
of calling the window's method. That's why I was attempting to subclass the
wxStaticBox directly.

By the way, thanks for all of your help Robin. You've patiently answered a
number of my questions and I see your name here a lot. You must spend petawods
of time doing this.



_______________________________________________
wxPython-users maillist  -  [hidden email]
http://starship.python.net/mailman/listinfo/wxpython-users