I've read so many questions similar to this but I'm caving in and making my own because nothing is working. Basically, I want to have my wx.StaticText
have vertically centered text while resizing with the window. My understanding is that existing solutions don't work because I care about the background of the StaticText
, and so I cannot simply vertically center the label itself in a sizer. I also see that it requires messy subclassing to have a transparent-background StaticText, so overlaying it on a panel sounds difficult.
Here is a minimal example (in my project the sizer has several other things in it):
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='Sample')
sizer=wx.BoxSizer(wx.VERTICAL)
label = wx.StaticText(self, -1, 'PLEASE VERTICALLY CENTER ME ;(', style=wx.ALIGN_CENTRE | wx.ST_NO_AUTORESIZE)
label.SetMinSize((300,300))
label.SetBackgroundColour((255,0,0))
sizer.Add(label, 1, wx.EXPAND | wx.ALL, 10)
self.SetSizerAndFit(sizer)
if __name__ == '__main__':
app=wx.App()
frame=MyFrame()
frame.Show()
app.MainLoop()
Despite that, it's hard to accept it's not simple to vertically center text. What is the easiest way to have the text in the label be vertically centered?
Solution: catalin's answer gave the concept necessary! Here is a full snippet for anyone else who encounters this problem. I added a button below the StaticText to demonstrate the vertical sizer remaining in control. The vertical sizer could be removed altogether if your application doesn't need it.
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='Sample')
sizer=wx.BoxSizer(wx.VERTICAL) # "main" sizer
panel = wx.Panel(self) # panel just for centering label
panel.SetBackgroundColour((255,0,0))
label = wx.StaticText(panel, -1, 'PLEASE VERTICALLY CENTER ME ;(', style=wx.ALIGN_CENTRE | wx.ST_NO_AUTORESIZE)
hsizer=wx.BoxSizer(wx.HORIZONTAL) # sizer for the panel
hsizer.Add(label, 1, wx.ALIGN_CENTER_VERTICAL)
panel.SetSizer(hsizer)
sizer.Add(panel, 1, wx.EXPAND)
btn = wx.Button(self, -1, 'Button')
sizer.Add(btn, 0, wx.EXPAND)
self.SetSizerAndFit(sizer)
if __name__ == '__main__':
app=wx.App()
frame=MyFrame()
frame.Show()
app.MainLoop()
In c++ a quick way would look like this:
wxPanel* p = new wxPanel(this); // you don't need to put it in a sizer if it's the only child
p->SetBackgroundColour({ 255, 0, 0 }); // this will be inherited by children
wxStaticText* label = new wxStaticText(p, wxID_ANY, "PLEASE VERTICALLY CENTER ME ;(");
wxSizer* s = new wxBoxSizer(wxHORIZONTAL); // for vertical one, you'd need stretch-spacers, and could not use wxALIGN_CENTER_VERTICAL, see below
s->Add(label, wxSizerFlags(1).Align(wxALIGN_CENTER_VERTICAL));
p->SetSizer(s);
Mind that if you want the text to wrap upon resize, wxStaticText
will probably not resize correctly, and you might need to replace it with something else.