wxpython:带背景的 StaticText 垂直居中文本
wxpython: StaticText vertically centered text with background
我已经阅读了很多与此类似的问题,但我陷入困境并提出自己的问题,因为没有任何效果。基本上,我想让 wx.StaticText
的文本垂直居中,同时使用 window 调整大小时。我的理解是现有解决方案不起作用,因为我关心 StaticText
的背景,所以我不能简单地将标签本身垂直居中于 sizer 中。我还看到它需要杂乱的子类化才能拥有透明背景的 StaticText,因此将其覆盖在面板上听起来很困难。
这是一个最小的例子(在我的项目中,sizer 中还有其他几个东西):
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()
尽管如此,很难接受将文本垂直居中并不简单。 使标签中的文本垂直居中的最简单方法是什么?
解法:
catalin 的回答给出了必要的概念!这是遇到此问题的任何其他人的完整代码段。我在 StaticText 下方添加了一个按钮,以演示垂直尺寸调整器仍在控制之中。如果您的应用程序不需要垂直尺寸调整器,则可以将其完全删除。
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()
在 C++ 中,快速方法如下所示:
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);
请注意,如果您希望文本在调整大小时换行,wxStaticText
可能无法正确调整大小,您可能需要将其替换为其他内容。
sizer 概念的另一个例子。
框架被分解成多个组成部分,每个部分都分配了相关的 sizer。
然后将组件 sizer 放入主(自身)sizer 中,将它们放在一起。
在这种情况下,组件是文本,需要居中放置,右侧有一组按钮,垂直堆叠。
显然,组件和安排不同,但将设计分解成多个部分然后组装以进行最终展示的概念保持不变。
事实上,复杂的组件通常需要应用相同的原理,在最终组件之前,在主 sizer 中留下一系列子组件。
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='Sample')
mainsizer=wx.BoxSizer(wx.HORIZONTAL) # "main" sizer
tsizer=wx.BoxSizer(wx.HORIZONTAL) # "text" sizer
bsizer=wx.BoxSizer(wx.VERTICAL) # "button" sizer
panel = wx.Panel(self) # panel for label
button_panel = wx.Panel(self) # panel for buttons
panel.SetBackgroundColour((190,0,0))
button_panel.SetBackgroundColour((160,0,0))
label = wx.StaticText(panel, -1, 'PLEASE VERTICALLY CENTER ME ;(')
btn1 = wx.Button(button_panel,-1, 'Button 1')
btn2 = wx.Button(button_panel,-1, 'Button 2')
btn3 = wx.Button(button_panel,-1, 'Button 3')
btn4 = wx.Button(button_panel,-1, 'Button 4')
tsizer.AddSpacer(10)
tsizer.Add(label, 0, wx.CENTER)
tsizer.AddSpacer(10) # Ensure gap between text and buttons
bsizer.Add(btn1)
bsizer.Add(btn2)
bsizer.Add(btn3)
bsizer.Add(btn4, 0, wx.BOTTOM, 35) # With space below
panel.SetSizer(tsizer)
button_panel.SetSizer(bsizer)
mainsizer.Add(panel, proportion=1, flag=wx.EXPAND) # panel to grow when resized
mainsizer.Add(button_panel, proportion=0, flag=wx.EXPAND) # panel to fill available space
self.SetSizerAndFit(mainsizer)
if __name__ == '__main__':
app=wx.App()
frame=MyFrame()
frame.Show()
app.MainLoop()
我已经阅读了很多与此类似的问题,但我陷入困境并提出自己的问题,因为没有任何效果。基本上,我想让 wx.StaticText
的文本垂直居中,同时使用 window 调整大小时。我的理解是现有解决方案不起作用,因为我关心 StaticText
的背景,所以我不能简单地将标签本身垂直居中于 sizer 中。我还看到它需要杂乱的子类化才能拥有透明背景的 StaticText,因此将其覆盖在面板上听起来很困难。
这是一个最小的例子(在我的项目中,sizer 中还有其他几个东西):
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()
尽管如此,很难接受将文本垂直居中并不简单。 使标签中的文本垂直居中的最简单方法是什么?
解法: catalin 的回答给出了必要的概念!这是遇到此问题的任何其他人的完整代码段。我在 StaticText 下方添加了一个按钮,以演示垂直尺寸调整器仍在控制之中。如果您的应用程序不需要垂直尺寸调整器,则可以将其完全删除。
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()
在 C++ 中,快速方法如下所示:
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);
请注意,如果您希望文本在调整大小时换行,wxStaticText
可能无法正确调整大小,您可能需要将其替换为其他内容。
sizer 概念的另一个例子。
框架被分解成多个组成部分,每个部分都分配了相关的 sizer。
然后将组件 sizer 放入主(自身)sizer 中,将它们放在一起。
在这种情况下,组件是文本,需要居中放置,右侧有一组按钮,垂直堆叠。
显然,组件和安排不同,但将设计分解成多个部分然后组装以进行最终展示的概念保持不变。
事实上,复杂的组件通常需要应用相同的原理,在最终组件之前,在主 sizer 中留下一系列子组件。
import wx
class MyFrame(wx.Frame):
def __init__(self):
super().__init__(None, title='Sample')
mainsizer=wx.BoxSizer(wx.HORIZONTAL) # "main" sizer
tsizer=wx.BoxSizer(wx.HORIZONTAL) # "text" sizer
bsizer=wx.BoxSizer(wx.VERTICAL) # "button" sizer
panel = wx.Panel(self) # panel for label
button_panel = wx.Panel(self) # panel for buttons
panel.SetBackgroundColour((190,0,0))
button_panel.SetBackgroundColour((160,0,0))
label = wx.StaticText(panel, -1, 'PLEASE VERTICALLY CENTER ME ;(')
btn1 = wx.Button(button_panel,-1, 'Button 1')
btn2 = wx.Button(button_panel,-1, 'Button 2')
btn3 = wx.Button(button_panel,-1, 'Button 3')
btn4 = wx.Button(button_panel,-1, 'Button 4')
tsizer.AddSpacer(10)
tsizer.Add(label, 0, wx.CENTER)
tsizer.AddSpacer(10) # Ensure gap between text and buttons
bsizer.Add(btn1)
bsizer.Add(btn2)
bsizer.Add(btn3)
bsizer.Add(btn4, 0, wx.BOTTOM, 35) # With space below
panel.SetSizer(tsizer)
button_panel.SetSizer(bsizer)
mainsizer.Add(panel, proportion=1, flag=wx.EXPAND) # panel to grow when resized
mainsizer.Add(button_panel, proportion=0, flag=wx.EXPAND) # panel to fill available space
self.SetSizerAndFit(mainsizer)
if __name__ == '__main__':
app=wx.App()
frame=MyFrame()
frame.Show()
app.MainLoop()