wxPython: GridBagSizer - Growable List Object

976 Views Asked by At

im using GridBagSizer for my UI Layout. Now im facing following problem.

the grid im using has 4 rows and 12 columns. on the second row (row 1) i ad a UltimateListCtrl and i want it to to grow if the window is resized vertically or horizontally.

ulc_style = ULC.ULC_REPORT | wx.LC_VRULES | wx.LC_HRULES | wx.LC_SINGLE_SEL | ULC.ULC_HAS_VARIABLE_ROW_HEIGHT
self.list = ulc = ULC.UltimateListCtrl(self.panel, agwStyle=ulc_style)    

self.sizer_grid = grid = wx.GridBagSizer(5,5)    
grid.Add(self.list, (1,0), (1,12), flag=wx.EXPAND)

I use the following function to make the columns growable and also set row 1 to be growable.

for i in range(13):
    grid.AddGrowableCol(i)
grid.AddGrowableRow(1)

I can resize the window horzizontally fine and alle elements resize with it but vertically the list stays where it is.

If i add size parameters to the ListCtrl the row will expand to the size i entered, and even expand further horizontally but vertically its still fixed to that size and wont adjust to the window size.

grid.AddGrowableRow(1)

Doesnt seem to do anything, when i remove it, the ui still looks the same. Im new to python and wxpython so maybe im doing something wrong.

Everything sits in a panel that sits in the frame, at end i call:

self.panel.SetSizerAndFit(self.sizer_grid)
1

There are 1 best solutions below

0
On

Ok, here is how i got it work like i wanted.

Full Code for the Window:

class ListView(wx.Frame):
def __init__( self, parent, id) :
    wx.Frame.__init__(self, wx.GetApp().TopWindow, title='Studenten Liste', size=(890, 740))

    self.panel = wx.Panel(self)

    # Font Mods
    font_underline = wx.Font(9, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, True)

    # Grid Sizer
    self.sizer_grid = grid = wx.GridBagSizer(5,5)

    # Row 0, Col 0+1
    self.label_auswahl = wx.StaticText(self.panel, label="Auswahl:")
    self.label_auswahl.SetFont(font_underline)
    grid.Add(self.label_auswahl, (0,0), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL)
    init_choice = ['TEMP1','TEMP2','TEMP3','TEMP4']
    self.input_auswahl = TextCtrlAutoComplete(self.panel, size=(280,24), choices=init_choice, showHead=False)
    grid.Add(self.input_auswahl, (0,1), (1,4), flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)

    # Row 0, Col 9,10,11
    self.label_kat = wx.StaticText(self.panel, label="Kategorie:")
    self.label_kat.SetFont(font_underline)
    grid.Add(self.label_kat, (0,9), flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL)
    kategorie_ch = ['Demo1', 'Demo2', 'Demo3']
    self.ch_kategorie = wx.Choice(self.panel, choices=kategorie_ch)
    self.ch_kategorie.db_name = 'kategorie'
    self.ch_kategorie.Bind(wx.EVT_CHOICE, self.OnKatChoice)
    grid.Add(self.ch_kategorie, (0,10), (1,2), flag=wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND)

    #Row 1, Col 0-12 - Ultimate List Ctrl
    self.list = ulc = UltimateLC(self.panel, 12)
    # Give it some columns.
    # The ID col we'll customize a bit:
    ulc.InsertColumn(0, 'Name:', width=120)
    ulc.InsertColumn(1, 'Vorname:', width=120)
    ulc.InsertColumn(2, 'Anschrift:', width=160)
    ulc.InsertColumn(3, 'Telefon:', width=100)
    ulc.InsertColumn(4, 'eMail:', width=200)
    ulc.InsertColumn(5, 'Studium:', format=ULC.ULC_FORMAT_CENTER, width=60)
    ulc.InsertColumn(6, 'Matr. Nr.:', format=ULC.ULC_FORMAT_CENTER, width=70)
    ulc.InsertColumn(7, 'Hauptfach:', width=100)
    ulc.InsertColumn(8, 'Nebenfach:', width=100)
    ulc.InsertColumn(9, 'Start Sem.:', width=70)
    ulc.InsertColumn(10, 'Letzte Akt.:', width=70)
    ulc.InsertColumn(11, 'Kategorie:', width=70)

    grid.Add(self.list, (1,0), (1,12), flag=wx.EXPAND)


    # Row 2+3
    self.label_sel = wx.StaticText(self.panel, label='Daten Drucken:')
    grid.Add(self.label_sel, (2,0), flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)

    # DICT Print Selection
    self.SelectDefs = SelectDefs = {
        # ID: ( Label, Header Name, DB Name, Column Width
        101 : ('Name', 'Name:', 'name', 0.9 ),
        102 : ('Vorame', 'Vorname:', 'vorname', 0.85 ),
        103 : ('Anschrift', 'Anschrift:', 'anschrift', 1.4 ),
        104 : ('Telefon', 'Telefon:', 'tele', 0.9 ),
        105 : ('eMail', 'eMail:', 'email', 1.65 ),
        106 : ('Studium', '', 'studium', 0.31 ),
        107 : ('Matrikel', 'Matrikel:', 'matrikel', 0.6 ),
        108 : ('Hauptfach', 'Haupftach:', 'hauptf', 0.9 ),
        109 : ('Nebenfach', 'Nebenfach:', 'nebenf', 0.9 ),
        110 : ('Start Sem.', 'Start:', 'startsem', 0.6 ),
        111 : ('Letzte Akt.', 'Last:', 'lastakt', 0.6 ),
        112 : ('Kategorie', '', 'kategorie', 0.5 ),
        }
    # Max Width for Portrait or Landscape printout
    self.max_portrait = 7.8
    self.max_landscape = 10.11

    keys = SelectDefs.keys()
    for i,k in enumerate(keys):
        col = i + 1
        row = 2
        if i > 5:
            col = i - 5
            row = 3
        label = SelectDefs[k][0]
        chk = wx.CheckBox(self.panel, k, label)
        grid.Add(chk, (row,col), flag=wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
        self.Bind(wx.EVT_CHECKBOX, self.OnCheckBox, chk)

    self.button_print_sel = wx.Button(self.panel, 201, label="Auswahl Drucken")
    self.button_print_sel.Bind(wx.EVT_BUTTON, self.OnPrint)
    self.button_print_all = wx.Button(self.panel, 202, label="Liste Drucken")
    self.button_print_all.Bind(wx.EVT_BUTTON, self.OnPrint)
    grid.Add(self.button_print_sel, (2,10), (2,1), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
    grid.Add(self.button_print_all, (2,11), (2,1), flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)

    # Column 8 will Expand, Column 8 only holds the ListCtrl
    grid.AddGrowableCol(8)
    # Row 1 will Expand, Row 1 only holds the ListCtrl
    grid.AddGrowableRow(1)

    # List Binds
    self.list.Bind(ULC.EVT_LIST_ITEM_CHECKED, self.OnCheck)
    self.list.Bind(ULC.EVT_LIST_ITEM_ACTIVATED, self.OnActivated)

    # Lists for the Checked Items
    self.checked_ids = []
    self.checked_sel = []

    # Set Defaults
    self.SetDefaults()

    # Set Min Windows Size
    self.SetMinSize((890, 540))

    # Main Sizer
    self.sizer_v = wx.BoxSizer(wx.VERTICAL)
    self.sizer_v.Add(grid, 1, wx.ALL | wx.EXPAND, 5)
    self.panel.SetSizerAndFit(self.sizer_v)

The Important Parts are:

  1. When Adding the List set the flag: wx.EXPAND

  2. Set all columns and rows you want to stretch with SetGrowable. In my example i only want the list to resize vertically and horizontally so i only set the row and column to growable that are the only ones holding the list. With this all other elements stay in their position, is it on the left or right.

  3. Finally adding everything to a vertical Boxsizer with proportion=1 and style wx.EXPAND. Proportion 1 allows the vertical stretch and the wx.EXPAND the horizontal. You could do the same with a horizontal boxsizer i guess. The wx.ALL and ',5' at the end only sets a margin arround the GridBagSizer which looks nicer imo.

PS: The code above needs some functions and custom widgets that are not included.

UltimaListCtrl (with Sorter Mixin):

self.list = ulc = UltimateLC(self.panel, 12)

can be replaced with:

self.list = list = wx.ListCtrl(self.panel, ...)

TextCtrlAutoComplete:

init_choice = ['TEMP1','TEMP2','TEMP3','TEMP4']
self.input_auswahl = TextCtrlAutoComplete(self.panel, size=(280,24), choices=init_choice, showHead=False)

which can be removed or replaced.

And a function that adds data and preselect some checkboxes:

self.SetDefaults()

This one can be removed as well.