Search code examples
pythonwxpythonwxwidgets

How to align things in wxpython


I have the following interface:

enter image description here

and my code is this:

child_frame = wx.Frame(self, title="Extension Options", size = (200,400), style=self.child_window_style)
    panel = wx.Panel(child_frame,-1)

    top_title = wx.StaticText(panel, id = -1, label = "Image Extensions")
    middle_title = wx.StaticText(panel, id = -1, label = "Document Extensions")
    bottom_title = wx.StaticText(panel, id = -1, label = "Miscellaneous")

    l = wx.StaticLine(panel, -1, style=wx.LI_HORIZONTAL, size = (200, 1))
    l2 = wx.StaticLine(panel, -1, style=wx.LI_HORIZONTAL, size = (200, 1))

    gif = wx.CheckBox(panel, label = ".gif")
    jpg = wx.CheckBox(panel, label = ".jpg")
    tif = wx.CheckBox(panel, label = ".tiff")
    png = wx.CheckBox(panel, label = ".png")

    word = wx.CheckBox(panel, label = "Word")
    excel = wx.CheckBox(panel, label = "Excel")
    access = wx.CheckBox(panel, label = "Access")
    powerpoint = wx.CheckBox(panel, label = "Power")

    line1_box = wx.BoxSizer(wx.HORIZONTAL)
    line2_box = wx.BoxSizer(wx.HORIZONTAL)
    #Create boxes
    main_box = wx.BoxSizer(wx.VERTICAL)
    img_box_title = wx.BoxSizer(wx.HORIZONTAL)# TITLE BOX
    main_img_box = wx.BoxSizer(wx.HORIZONTAL)
    img_box1 = wx.BoxSizer(wx.VERTICAL)
    img_box2 = wx.BoxSizer(wx.VERTICAL)
    doc_box_title = wx.BoxSizer(wx.HORIZONTAL)# TITLE BOX
    main_doc_box = wx.BoxSizer(wx.HORIZONTAL)
    doc_box1 = wx.BoxSizer(wx.VERTICAL)
    doc_box2 = wx.BoxSizer(wx.VERTICAL)
    misc_box_title = wx.BoxSizer(wx.HORIZONTAL)
    #main_misc_box = wx.BoxSizer(wx.HORIZONTAL)

    #Place elements to boxes
    img_box_title.Add(top_title, 1, wx.ALIGN_CENTER|wx.ALL, 5)# ASSIGN TITLE
    img_box1.Add(gif, 1, wx.ALIGN_LEFT|wx.ALL, 5)
    img_box1.Add(jpg, 1, wx.ALIGN_LEFT|wx.ALL, 5)
    img_box2.Add(tif, 1, wx.ALIGN_LEFT|wx.ALL, 5)
    img_box2.Add(png, 1, wx.ALIGN_LEFT|wx.ALL, 5)
    line1_box.Add(l, 0, wx.CENTER, 1)# LINE
    doc_box_title.Add(middle_title, 1, wx.ALIGN_CENTER|wx.ALL, 5)# ASSIGN TITLE
    doc_box1.Add(word, 1, wx.ALIGN_LEFT|wx.ALL, 5)
    doc_box1.Add(access, 1, wx.ALIGN_LEFT|wx.ALL, 5)
    doc_box2.Add(excel, 1, wx.ALIGN_LEFT|wx.ALL, 5)
    doc_box2.Add(powerpoint, 1, wx.ALIGN_LEFT|wx.ALL, 5)
    line2_box.Add(l2, 0, wx.CENTER, 1)# LINE
    misc_box_title.Add(bottom_title, 1, wx.ALIGN_CENTER|wx.ALL, 5)# ASSIGN TITLE

    #Place boxes
    main_box.Add(img_box_title, 1, wx.ALIGN_CENTER, 5)# PLACE TITLE
    main_box.Add(main_img_box, 1, wx.ALIGN_CENTER, 5)
    main_img_box.Add(img_box1, 1, wx.ALIGN_CENTER, 5)
    main_img_box.Add(img_box2, 1, wx.ALIGN_CENTER, 5)
    main_box.Add(line1_box, 0, wx.ALIGN_CENTER, 0)# LINE
    main_box.Add(doc_box_title, 1, wx.ALIGN_CENTER, 5)# PACE TITLE
    main_box.Add(main_doc_box, 1, wx.ALIGN_CENTER, 5)
    main_doc_box.Add(doc_box1, 1, wx.ALIGN_CENTER, 5)
    main_doc_box.Add(doc_box2, 1, wx.ALIGN_CENTER, 5)
    main_box.Add(line2_box, 0, wx.ALIGN_CENTER, 0)# LINE
    main_box.Add(misc_box_title, 1, wx.ALIGN_CENTER, 5)# PACE TITLE


    panel.SetSizer(main_box)
    wx.Frame.CenterOnScreen(child_frame)
    child_frame.Show()

Is there any way to align the "gif - jpg" with the "word - access"?

I could make it a static window and use pos, but i want to learn to use box sizers as well...


Solution

  • There is no convenient way to align items across sizers, unfortunately. So either you have to use a single sizer including the elements you want to align and everything between them, and in your case wxGridBagSizer recommended by @sebdelsol is the only sizer which would work.

    Or you could help the sizer layout algorithm slightly. To do this, you need to compute the maximal width of your column(s), by iterating over the results of GetBestSize() applied to all the checkboxes in a column. And then you should use wxSizer::SetItemMinSize() to set this width for all of them, including the ones in the different sizer.

    Notice that independently of the above, your layout could be simplified by using wxFlexGridSizer instead of so many box sizers.