I see this come up from time to time where people will ask how to center a widget in a window. The solution is actually quite easy. In most cases, you just need to nest a Horizontal BoxSizer inside of a Verticel BoxSizer with some spacers. In this article, I'll show you two three different ways to accomplish this task.
The first time I learned how to do this, I was told I could use a tuple for my spacer. The syntax looks a bit odd, but it works:
import wx ######################################################################## class MainFrame(wx.Frame): """""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" wx.Frame.__init__(self, None, title="Center the Button") panel = wx.Panel(self) h_sizer = wx.BoxSizer(wx.HORIZONTAL) main_sizer = wx.BoxSizer(wx.VERTICAL) btn = wx.Button(panel, label="Centered") h_sizer.Add(btn, 0, wx.CENTER) main_sizer.Add((0,0), 1, wx.EXPAND) main_sizer.Add(h_sizer, 0, wx.CENTER) main_sizer.Add((0,0), 1, wx.EXPAND) panel.SetSizer(main_sizer) self.Show() if __name__ == "__main__": app = wx.App(False) frame = MainFrame() app.MainLoop()
Here we nest a horizontal sizer inside out top-level vertical sizer. But we surround the horizontal sizer with two "spacers" that happen to be tuples that have both their proportions set to 1 and the wx.EXPAND style flag set.
wxPython's sizer's include AddStretchSpacer, which is a nice convenience method that does basically the same thing as above. Let's take a look:
import wx ######################################################################## class MainFrame(wx.Frame): """""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" wx.Frame.__init__(self, None, title="Center the Button") panel = wx.Panel(self) h_sizer = wx.BoxSizer(wx.HORIZONTAL) main_sizer = wx.BoxSizer(wx.VERTICAL) btn = wx.Button(panel, label="Centered") h_sizer.Add(btn, 0, wx.CENTER) main_sizer.AddStretchSpacer(prop=1) main_sizer.Add(h_sizer, 0, wx.CENTER) main_sizer.AddStretchSpacer(prop=1) panel.SetSizer(main_sizer) self.Show() if __name__ == "__main__": app = wx.App(False) frame = MainFrame() app.MainLoop()
You will note that the only difference here is using the AddStretchSpacer method along with its prop parameter set to 1.
One of my astute readers mentioned a third way to center the widget that does not require nesting the sizers. Let's take a look:
import wx class MainFrame(wx.Frame): """""" #---------------------------------------------------------------------- def __init__(self): """Constructor""" wx.Frame.__init__(self, None, title="Center the Button") panel = wx.Panel(self) main_sizer = wx.BoxSizer(wx.VERTICAL) btn = wx.Button(panel, label="Centered") main_sizer.AddStretchSpacer() main_sizer.Add(btn, 0, wx.CENTER) main_sizer.AddStretchSpacer() panel.SetSizer(main_sizer) self.Show() if __name__ == "__main__": app = wx.App(False) frame = MainFrame() app.MainLoop()
Here we just create a vertical sizer, add a stretch spacer and then tell the button to be centered, then add another stretch spacer. The code is very similar to the previous example except that we don't use a horizontal sizer at all. Special thanks goes to Yoriz for mentioned this to me in the comments.
Copyright © 2024 Mouse Vs Python | Powered by Pythonlibrary