How would you code this UI?

Hello,

I’m still learning about sizers in wxPython, and not sure how to get this type of UI.

What sizer should I use, and how?

Thank you.

GridBagSizer.

Here’s a quick draft to produce your layout that uses my own wxWize library. I didn’t bother fiddling with the spacing, you’d need to add in some border= to get that aspect of your layout right.

The x= and xspan= atts. are a wxWize convenience. If you use something other than wxWize, then look for the pos and span parameters of the Add method to achieve the same thing.

import wx
import wize as iz

class ShorehsFrame(wx.Frame):
    def __init__(self, parent):
        with iz.Frame("my app", init=self, parent=parent):
            with iz.Panel():
                with iz.GridBagSizer():
                    iz.StaticText("input file", x=0)
                    self._input_file_edit = iz.TextCtrl().wx
                    iz.Button("Build", x=5, EVT_BUTTON=self._OnBuild)
                    iz.Button("Clear", EVT_BUTTON=self._OnClear)

                    iz.StaticText("ss", x=0)
                    self._ss_edit = iz.TextCtrl().wx

                    iz.StaticText("to", x=0)
                    self._to_edit = iz.TextCtrl().wx
                    self._bitrate_check = iz.CheckBox("Bit rate").wx
                    self._size_check = iz.CheckBox("Size").wx
                    self._louder_check = iz.CheckBox("Louder").wx

                    iz.StaticText("output", x=0)
                    self._output_edit = iz.TextCtrl(x=1, xspan=6, flag=wx.EXPAND).wx

        self.Fit()

    def _OnBuild(self, event):
        print("Build button pressed")

    def _OnClear(self, event):
        print("Clear button pressed")

if __name__=='__main__':
    app = wx.App()
    fr = ShorehsFrame(None)
    fr.Show(True)
    app.MainLoop()
1 Like

The easiest way to arrange UI elements is to use a GUI builder:
wx Basics — wxGlade 1.1.1 documentation

Doing each and everything by handcrafting code is tedious. That’s probably the reason why so many people (including myself) once did wrappers like the one that Anders has shown. I don’t use mine any more for new projects.

Handcrafting code is OK for the main window / document window of an application. For dialogs I’m doing it rarely.

2 Likes

GridBagExample.zip (2.2 KB)

Thanks much.

So a solution is to use two BoxSizers (one vertical, the other horizontal) and a GridBagsizer, where the horizontal BoxSizer is inserted at the bottom of the GridBag:

sizer_1 = wx.BoxSizer(wx.VERTICAL)
grid_sizer_1 = wx.GridBagSizer(4, 4)
sizer_1.Add(grid_sizer_1, 1, wx.ALL | wx.EXPAND, 7)
…
sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
grid_sizer_1.Add(sizer_2, (2, 2), (1, 1), wx.EXPAND, 0)
…
grid_sizer_1.AddGrowableCol(2)
self.SetSizer(sizer_1)

For a beginner (as I still am with WX) I found manually coding the window, panel, and size layouts was very useful to understand how the expand, vertical/horizontal etc were working.

The latest version of WX is also more restrictive and won’t allow invalid options/styles etc so the error message are more helpful to understand what you have done wrong.

GridBagSizer is the most useful for complex layouts as others have suggested.

Once you have the layout as you want, I find the StaticBox, StaticBoxSizer inside the gridBagSizer more professional looking for a UI

I would second the option of using a UI builder. In particular, as a beginner this approach will let you quickly explore and become familiar with the various options. I use: GitHub - wxFormBuilder/wxFormBuilder: A wxWidgets GUI Builder.

Remark that in addition to C++ and XML code usable in wxWidgets it can also generate python code compatible with the latest release of wxPython, which you can use in your project directly, or to learn to code the UI manually, if that is your preference.

2 Likes

You could remove the outer BoxSizer. It’s just there to allow some border around the GridBagSizer. You could experiment with adding borders to the items in the GridBagSizer instead.