= How to create a box sizer (Phoenix) =
'''Keywords :''' Box sizer.

<<TableOfContents>>

--------
= Introduction : =
Let's make a program in which three buttons will occupy one row placed at the top of the window.

These buttons will resize when the window is resized.

We can place widgets vertically or horizontally.

{{{
box = wx.BoxSizer(integer orient)
}}}
Where orientation can be '''wx.VERTICAL''' or '''wx.HORIZONTAL'''.

Adding widgets into the {{{wx.BoxSizer}}} is done via the {{{Add()}}} method.

In order to understand it, we need to look at its parameters.

{{{
Add(wx.Window window, integer proportion=0, integer flag=0, integer border=0)
}}}
'''The proportion''' parameter defines the share or ratio of available sizer space

that the widget will  occupy in the direction of the defined orientation.

Let's assume we have three buttons with the proportions 0, 1, and 2.

They are added into a horizontal {{{wx.BoxSizer}}}.

The button with proportion 0 will not change at all when the sizer's width

(horizontal size) changes (i.e. the button will always be the same width).

The rest of the width of the sizer is split into 3 (2+1) shares.

The button with proportion 2 will always occupy 2 of those 3 shares

(its width will be 2/3 of the available width), and the button with

proportion 1 will always occupy 1 of those shares.

With the flag parameter, you can further configure the behaviour

of the widgets within a {{{wx.BoxSizer}}}.

We can control the border (though "padding" would be a more

accurate name than "border") between the widgets.

We add some space between widgets in pixels.

In order to apply border, we need to define which sides will use the border.

We can choose between these '''flags''' :

 * wx.LEFT
 * wx.RIGHT
 * wx.BOTTOM
 * wx.TOP
 * wx.ALL

We can combine them with the | operator. e.g {{{wx.LEFT}}} | {{{wx.BOTTOM}}}.

If we use {{{wx.EXPAND}}} flag, our widget will use all the space that is available

in the direction perpendicular to the sizer's orient direction.

Lastly, we can also define the alignment of our widgets.

We do it with the following '''flags''' :

 * wx.ALIGN_LEFT
 * wx.ALIGN_RIGHT
 * wx.ALIGN_TOP
 * wx.ALIGN_BOTTOM
 * wx.ALIGN_CENTER_VERTICAL
 * wx.ALIGN_CENTER_HORIZONTAL
 * wx.ALIGN_CENTER

(info by '''ZetCode / Jan Bodnar''').
--------
= Demonstrating : =
__'''''Tested''' py3.x, wx4.x and Win10. ''__

Are you ready to use some samples ? ;)

Test, modify, correct, complete, improve and share your discoveries ! (!)

--------
== Sample one ==
{{attachment:img_sample_one.png}}

{{{#!python
# Sample_one.py

"""

https://maku77.github.io/python/wxpython/layout.html

sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer = wx.BoxSizer(wx.VERTICAL)

"""

import wx

# class MyFrame
# class MyApp

#---------------------------------------------------------------------------

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, None, -1, title, size=(350, 150))

        self.SetIcon(wx.Icon('./icons/wxwin.ico', wx.BITMAP_TYPE_ICO))

        #------------
        
        self.InitializeComponents()

    #-----------------------------------------------------------------------

    def InitializeComponents(self):
        mainPanel = wx.Panel(self)
        
        button1 = wx.Button(mainPanel, -1, "Button 1")
        button2 = wx.Button(mainPanel, -1, "Button 2")
        button3 = wx.Button(mainPanel, -1, "Button 3")

        #------------
        
        # Create a sizer.
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        
        sizer.Add(button1)
        sizer.Add(button2)
        sizer.Add(button3)
        
        mainPanel.SetSizer(sizer)

#---------------------------------------------------------------------------
        
class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, "wx.BoxSizer")
        frame.Show(True)
        
        return True
    
#---------------------------------------------------------------------------

def main():
    app = MyApp(redirect=False)
    app.MainLoop()

#---------------------------------------------------------------------------

if __name__ == "__main__" :
    main()
}}}
--------
== Sample two ==
{{attachment:img_sample_two.png}}

{{{#!python
# sample_two.py

"""

Author : Jan Bodnar
Website : zetcode.com

"""

import wx

# class MyFrame
# class MyApp

#---------------------------------------------------------------------------

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title,
                          (-1, -1), wx.Size(300, 100))

        self.SetIcon(wx.Icon('./icons/wxwin.ico', wx.BITMAP_TYPE_ICO))

        #------------
        
        panel = wx.Panel(self, -1)

        #------------
        
        box = wx.BoxSizer(wx.HORIZONTAL)

        box.Add(wx.Button(panel, -1, 'Button1'), 1 )
        box.Add(wx.Button(panel, -1, 'Button2'), 1 )
        box.Add(wx.Button(panel, -1, 'Button3'), 1 )

        panel.SetSizer(box)

        #------------
        
        self.Centre()

#---------------------------------------------------------------------------
        
class MyApp(wx.App):
     def OnInit(self):
         frame = MyFrame(None, -1, 'wx.BoxSizer')
         frame.Show(True)
         
         return True

#---------------------------------------------------------------------------
        
app = MyApp(0)
app.MainLoop()
}}}
--------
== Sample three ==
{{attachment:img_sample_three.png}}

{{{#!python
# Sample_three.py

"""

https://maku77.github.io/python/wxpython/layout.html

sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer = wx.BoxSizer(wx.VERTICAL)

"""

import wx

# class MyFrame
# class MyApp

#---------------------------------------------------------------------------

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, None, -1, title, size=(350, 150))

        self.SetIcon(wx.Icon('./icons/wxwin.ico', wx.BITMAP_TYPE_ICO))

        #------------
        
        self.InitializeComponents()

    #-----------------------------------------------------------------------
        
    def InitializeComponents(self):
        mainPanel = wx.Panel(self)
        
        button1 = wx.Button(mainPanel, -1, "Button 1")
        button2 = wx.Button(mainPanel, -1, "Button 2")
        button3 = wx.Button(mainPanel, -1, "Button 3")

        #------------
        
        # Create a sizer.
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        
        sizer.Add(button1, 1, wx.ALIGN_TOP)
        sizer.Add(button2, 1, wx.ALIGN_CENTER)
        sizer.Add(button3, 1, wx.ALIGN_BOTTOM)
        
        mainPanel.SetSizer(sizer)

#---------------------------------------------------------------------------
        
class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, "wx.BoxSizer (wx.ALIGN_x)")
        frame.Show(True)
        
        return True
    
#---------------------------------------------------------------------------

def main():
    app = MyApp(redirect=False)
    app.MainLoop()

#---------------------------------------------------------------------------

if __name__ == "__main__" :
    main()
}}}
--------
== Sample four ==
{{attachment:img_sample_four.png}}

{{{#!python
# Sample_four.py

"""

https://maku77.github.io/python/wxpython/layout.html

sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer = wx.BoxSizer(wx.VERTICAL)

"""

import wx

# class MyFrame
# class MyApp

#---------------------------------------------------------------------------

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, None, -1, title, size=(350, 150))

        self.SetIcon(wx.Icon('./icons/wxwin.ico', wx.BITMAP_TYPE_ICO))

        #------------
        
        self.InitializeComponents()

    #-----------------------------------------------------------------------

    def InitializeComponents(self):
        mainPanel = wx.Panel(self)
        
        button1 = wx.Button(mainPanel, -1, "Button 1")
        button2 = wx.Button(mainPanel, -1, "Button 2")
        button3 = wx.Button(mainPanel, -1, "Button 3")

        #------------
        
        # Create a sizer.
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        
        sizer.Add(button1, 1)
        sizer.Add(button2, 1)
        sizer.Add(button3, 2)
        
        mainPanel.SetSizer(sizer)

#---------------------------------------------------------------------------
        
class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, "wx.BoxSizer (proportion)")
        frame.Show(True)
        
        return True
    
#---------------------------------------------------------------------------

def main():
    app = MyApp(redirect=False)
    app.MainLoop()

#---------------------------------------------------------------------------

if __name__ == "__main__" :
    main()
}}}
--------
== Sample five ==
{{attachment:img_sample_five.png}}

{{{#!python
# Sample_five.py

"""

https://maku77.github.io/python/wxpython/layout.html

sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer = wx.BoxSizer(wx.VERTICAL)

"""

import wx

# class MyFrame
# class MyApp

#---------------------------------------------------------------------------

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, None, -1, title, size=(350, 150))

        self.SetIcon(wx.Icon('./icons/wxwin.ico', wx.BITMAP_TYPE_ICO))

        #------------
        
        self.InitializeComponents()

    #-----------------------------------------------------------------------

    def InitializeComponents(self):
        mainPanel = wx.Panel(self)
        
        button1 = wx.Button(mainPanel, -1, "Button 1")
        button2 = wx.Button(mainPanel, -1, "Button 2")
        button3 = wx.Button(mainPanel, -1, "Button 3")

        # Create a sizer.
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        
        sizer.Add(button1, 1, wx.EXPAND)
        sizer.Add(button2, 1, wx.EXPAND)
        sizer.Add(button3, 1)
        
        mainPanel.SetSizer(sizer)

#---------------------------------------------------------------------------
        
class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, "wx.BoxSizer (wx.EXPAND)")
        frame.Show(True)
        
        return True
    
#---------------------------------------------------------------------------

def main():
    app = MyApp(redirect=False)
    app.MainLoop()

#---------------------------------------------------------------------------

if __name__ == "__main__" :
    main()
}}}
--------
== Sample six ==
{{attachment:img_sample_six.png}}

In our example we again have three buttons.

The first one has some border around all its sides.

It is the only one that changes in the horizontal  dimension when the main window is resized.

The second one occupies all space alloted to it  in the vertical direction.

The third one is aligned in the centre.

We can combine various {{{wx.BoxSizer}}}.

For example, we can put several horizontal {{{wx.BoxSizer}}}  into a vertical {{{wx.BoxSizer}}} and vice versa.

This way we can make complex layouts.

{{{#!python
# Sample_six.py

"""

Author : Jan Bodnar
Website : zetcode.com

"""

import wx

# class MyFrame
# class MyApp

#---------------------------------------------------------------------------

class MyFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title,
                         (-1, -1), wx.Size(350, 150))

        self.SetIcon(wx.Icon('./icons/wxwin.ico', wx.BITMAP_TYPE_ICO))

        #------------
        
        panel = wx.Panel(self, -1)

        #------------
        
        box = wx.BoxSizer(wx.HORIZONTAL)
        
        box.Add(wx.Button(panel, -1, 'Button1'), 1, wx.ALL, 5)
        box.Add(wx.Button(panel, -1, 'Button2'), 0, wx.EXPAND)
        box.Add(wx.Button(panel, -1, 'Button3'), 0, wx.ALIGN_CENTER)
        
        panel.SetSizer(box)

        #------------
        
        self.Centre()

#---------------------------------------------------------------------------
        
class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(None, -1, 'wx.BoxSizer')
        frame.Show(True)
        
        return True

#---------------------------------------------------------------------------
    
app = MyApp(0)
app.MainLoop()
}}}
--------

= Download source =
[[attachment:source.zip]]

--------
= Additional Information =
'''Link :'''

- - - - -

https://wiki.wxpython.org/TitleIndex

https://docs.wxpython.org/

--------
= Thanks to =
Maku77 (sample_one / three / four / five.py coding), Jan Bodnar (sample_two / six.py coding), the wxPython community...

--------
= About this page =
Date(d/m/y)     Person (bot)    Comments :

15/12/20 - Ecco (Created page for wxPython Phoenix).

--------
= Comments =
- blah, blah, blah...