【问题标题】:wxpython: StaticText vertically centered text with backgroundwxpython:StaticText 垂直居中的带有背景的文本
【发布时间】:2022-01-10 04:26:24
【问题描述】:

我已经阅读了很多与此类似的问题,但我正在屈服并提出自己的问题,因为没有任何效果。基本上,我希望我的wx.StaticText 在调整窗口大小时具有垂直居中的文本。我的理解是现有的解决方案不起作用,因为我关心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()

尽管如此,很难接受垂直居中文本并不简单。 让标签中的文本垂直居中的最简单方法是什么?


解决方案: 卡特林的回答给出了必要的概念!对于遇到此问题的其他任何人,这是一个完整的 sn-p。我在 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()

【问题讨论】:

  • 为什么需要wxEXPAND | wxALL?你不能用wxEXPAND | wxALIGN_CENTER_VERTICAL吗?
  • @Igor 据我所知,这些是不同的东西。 wx.ALL 只是意味着我想要一个边框,这不是一个重要的细节。不过,最重要的是,ALIGN_CENTER_VERTICAL 会对齐标签本身,而不是标签中的文本。它也与 wx.EXPAND 不兼容(如果标签占用了它所能占用的所有空间,那么就没有空间来对齐/居中它)。

标签: python wxpython wxwidgets


【解决方案1】:

在 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 可能无法正确调整大小,您可能需要将其替换为其他内容。

【讨论】:

  • 谢谢!!这个概念非常有效。我为这个问题添加了一个 Python 解决方案。
【解决方案2】:

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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 2013-10-15
    • 2012-11-06
    • 2020-09-15
    • 2015-09-16
    相关资源
    最近更新 更多