【问题标题】:How to force a widget down in wxPython如何在 wxPython 中强制关闭小部件
【发布时间】:2018-08-12 22:32:14
【问题描述】:

我正在使用 wxWidgets (wxPython) 为我的 python 项目构建 GUI。有一个小但烦人的问题,我似乎无法弄清楚。三个按钮 START、CROSS 和 BROWSE 应该在窗口的底部。这些是wx.ToggleButton 小部件,它们属于水平BoxSizer,而后者又是名为leftmost_box 的垂直BoxSizer 的子级。 问题是,如何将这些按钮向下压到最左角?我尝试设置标志,即wx.ALIGN_BOTTOM,但它不起作用。

附上源代码。

import wx

#################################
# Set up the application window #
#################################

app = wx.App()
mainframe = wx.Frame(None, -1)
mainframe.SetSize((900, 500))
mainframe.SetTitle('Mdl')
panel = wx.Panel(mainframe, -1)
panel.SetBackgroundColour('grey')

# Setting the default font #
#wx.Font(pointSize, family, style,  weight, faceName="")
panel.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.LIGHT, faceName = 'Helvetica'))


####################
# Global variables #
####################

choices = ['SAT Exam', 'Top 300', 'Custom Dictionary', 'Advanced English']
word_of_the_day   = wx.StaticText(panel, label = 'Prowess: skill or expertise in a particular activity or field: her culinary prowess.', size = (180, 190))

#Throwaway var for testing
_word_of_the_day   = wx.StaticText(panel, label = 'Prowess: skill or expertise in a particular activity or field: her culinary prowess.', size = (180, 190))

####################
# Controls go here #
####################

searchbar_wgt                = wx.SearchCtrl(panel, value = 'Search...', size = (210, -1))
pick_active_dictionary_wgt   = wx.Choice(panel, choices = choices, size = (170, -1))
active_dictionary_size_wgt   = wx.SpinCtrl(panel, min = 0, max = 50, initial = 15, size = (50, -1))
button_next_wgt              = wx.Button(panel, label = 'Next >')
button_back_wgt              = wx.Button(panel, label = '< Back')
set_word_order_wgt           = wx.RadioBox(panel, label = 'Order', choices = ['Normal', 'Random'])
logo_image                   = wx.Image('logo.png', wx.BITMAP_TYPE_ANY).Scale(285, 63)
bitmap_logo_image            = wx.StaticBitmap(panel, -1, logo_image.ConvertToBitmap())
start_mode_button_wgt        = wx.ToggleButton(panel, label = 'Start')
crossword_mode_button_wgt    = wx.ToggleButton(panel, label = 'Cross')
browse_mode_button_wgt       = wx.ToggleButton(panel, label = 'Browse')


###################
# Standard Layout #
###################

main_box      = wx.BoxSizer(wx.HORIZONTAL)
leftmost_box  = wx.BoxSizer(wx.VERTICAL)
central_box   = wx.BoxSizer(wx.VERTICAL)
rightmost_box = wx.BoxSizer(wx.VERTICAL)

#############
# Subsizers #
#############
leftmost_box_subsizer   = wx.BoxSizer(wx.HORIZONTAL)

static_box_central      = wx.StaticBox(panel, label = 'Card #', size = (180, 180))
static_box_szr_central  = wx.StaticBoxSizer(static_box_central, wx.VERTICAL)

static_box_left         = wx.StaticBox(panel, label = 'Vocabulary Options')
static_box_szr_left     = wx.StaticBoxSizer(static_box_left, wx.VERTICAL)

static_box_right        = wx.StaticBox(panel, label = 'Word of the Day', size = (200, 200))
static_box_szr_right    = wx.StaticBoxSizer(static_box_right, wx.VERTICAL)


static_box_szr_right.Add(word_of_the_day, 1, wx.ALL, 5)
static_box_szr_left.AddMany([
                           (    pick_active_dictionary_wgt, 1, wx.ALL,                                    5 ),
                           (    active_dictionary_size_wgt, 1, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.ALIGN_RIGHT, 5 ),
                           (    set_word_order_wgt,         1, wx.LEFT|wx.RIGHT|wx.ALIGN_RIGHT,           5 )
                           ])

# Changes the Label (NB: StaticBox can be reused to display definitions)
# static_box.SetLabel('Definition')
# To create an SB widget, you need to create an SBS and pass an SB to it as an argument
# It will then behave as a regular sizer

main_box.AddMany([
                (   leftmost_box,   1, wx.ALL,           10 ),
                (   central_box,    1, wx.TOP|wx.BOTTOM, 10 ),
                (   rightmost_box,  1, wx.ALL,           10 )
                ])

static_box_szr_central.Add(_word_of_the_day, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)

# Building the rightmost box
rightmost_box.Add(searchbar_wgt, 1, wx.ALIGN_RIGHT)
rightmost_box.Add(static_box_szr_right, 8, wx.TOP|wx.ALIGN_RIGHT, 50)

# Building the leftmost box
leftmost_box.Add(static_box_szr_left, 2, wx.ALL|wx.ALIGN_LEFT, 10)
leftmost_box.Add(leftmost_box_subsizer, 1, wx.ALL|wx.EXPAND, 10)

# Building the leftmost subsizer
leftmost_box_subsizer.AddMany([
                             (  start_mode_button_wgt,     wx.TOP|wx.BOTTOM|wx.ALIGN_BOTTOM, 10 ),
                             (  crossword_mode_button_wgt, wx.TOP|wx.BOTTOM|wx.ALIGN_BOTTOM, 10 ),
                             (  browse_mode_button_wgt,    wx.TOP|wx.BOTTOM|wx.ALIGN_BOTTOM, 10 )
                             ])

#Toggle the start mode button
start_mode_button_wgt.SetValue(True)

# The pLexis logo
central_box.Add(bitmap_logo_image, 1, wx.ALL|wx.ALIGN_CENTRE, 5)
# The word card
central_box.Add(static_box_szr_central, 2, wx.ALL|wx.ALIGN_CENTRE, 5)

# Kick it!
panel.SetSizer(main_box)
mainframe.Show()
app.MainLoop()

【问题讨论】:

    标签: python user-interface wxpython


    【解决方案1】:

    您在 sizer 中的 proportion 值到处都是,并且在一定程度上,flag 条目也是如此。

    1. 清理proportion
    2. 添加 NEXT 和 BACK 按钮(您忘记将它们添加到 sizer)
    3. leftmost_box 添加一个比例=1 的虚拟项目(强制最后一个项目到底部)
    4. 在将leftmost_box 添加到主尺寸器时设置 EXPAND 标志

    我认为仅此而已。

    import wx
    
    #################################
    # Set up the application window #
    #################################
    
    app = wx.App()
    mainframe = wx.Frame(None, -1)
    mainframe.SetSize((900, 500))
    mainframe.SetTitle('Mdl')
    panel = wx.Panel(mainframe, -1)
    panel.SetBackgroundColour('grey')
    
    # Setting the default font #
    #wx.Font(pointSize, family, style,  weight, faceName="")
    panel.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.LIGHT, faceName = 'Helvetica'))
    
    
    ####################
    # Global variables #
    ####################
    
    choices = ['SAT Exam', 'Top 300', 'Custom Dictionary', 'Advanced English']
    word_of_the_day   = wx.StaticText(panel, label = 'Prowess: skill or expertise in a particular activity or field: her culinary prowess.', size = (180, 190))
    
    #Throwaway var for testing
    _word_of_the_day   = wx.StaticText(panel, label = 'Prowess: skill or expertise in a particular activity or field: her culinary prowess.', size = (180, 190))
    
    ####################
    # Controls go here #
    ####################
    
    searchbar_wgt                = wx.SearchCtrl(panel, value = 'Search...', size = (210, -1))
    pick_active_dictionary_wgt   = wx.Choice(panel, choices = choices, size = (170, -1))
    active_dictionary_size_wgt   = wx.SpinCtrl(panel, min = 0, max = 50, initial = 15, size = (50, -1))
    button_next_wgt              = wx.Button(panel, label = 'Next >')
    button_back_wgt              = wx.Button(panel, label = '< Back')
    set_word_order_wgt           = wx.RadioBox(panel, label = 'Order', choices = ['Normal', 'Random'])
    logo_image                   = wx.Image('logo.png', wx.BITMAP_TYPE_ANY).Scale(285, 63)
    bitmap_logo_image            = wx.StaticBitmap(panel, -1, logo_image.ConvertToBitmap())
    start_mode_button_wgt        = wx.ToggleButton(panel, label = 'Start')
    crossword_mode_button_wgt    = wx.ToggleButton(panel, label = 'Cross')
    browse_mode_button_wgt       = wx.ToggleButton(panel, label = 'Browse')
    
    
    ###################
    # Standard Layout #
    ###################
    
    main_box      = wx.BoxSizer(wx.HORIZONTAL)
    leftmost_box  = wx.BoxSizer(wx.VERTICAL)
    central_box   = wx.BoxSizer(wx.VERTICAL)
    rightmost_box = wx.BoxSizer(wx.VERTICAL)
    
    #############
    # Subsizers #
    #############
    leftmost_box_subsizer   = wx.BoxSizer(wx.HORIZONTAL)
    
    static_box_central      = wx.StaticBox(panel, label = 'Card #', size = (180, 180))
    static_box_szr_central  = wx.StaticBoxSizer(static_box_central, wx.VERTICAL)
    
    static_box_left         = wx.StaticBox(panel, label = 'Vocabulary Options')
    static_box_szr_left     = wx.StaticBoxSizer(static_box_left, wx.VERTICAL)
    
    static_box_right        = wx.StaticBox(panel, label = 'Word of the Day', size = (200, 200))
    static_box_szr_right    = wx.StaticBoxSizer(static_box_right, wx.VERTICAL)
    
    
    static_box_szr_right.Add(word_of_the_day, 0, wx.ALL, 5)
    static_box_szr_left.AddMany([
                               (    pick_active_dictionary_wgt, 0, wx.ALL, 5 ),
                               (    active_dictionary_size_wgt, 0, wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.ALIGN_RIGHT, 5 ),
                               (    set_word_order_wgt, 0, wx.LEFT|wx.RIGHT|wx.ALIGN_RIGHT, 5 )
                               ])
    
    # Changes the Label (NB: StaticBox can be reused to display definitions)
    # static_box.SetLabel('Definition')
    # To create an SB widget, you need to create an SBS and pass an SB to it as an argument
    # It will then behave as a regular sizer
    
    main_box.AddMany([
                    (   leftmost_box,   0, wx.EXPAND|wx.ALL, 10 ),
                    (   central_box,    0, wx.TOP|wx.BOTTOM, 10 ),
                    (   rightmost_box,  0, wx.ALL,           10 )
                    ])
    
    static_box_szr_central.Add(_word_of_the_day, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5)
    
    # Building the rightmost box
    rightmost_box.Add(button_next_wgt, 0, wx.ALL|wx.ALIGN_LEFT, 10)
    rightmost_box.Add(searchbar_wgt, 0, wx.ALIGN_RIGHT)
    rightmost_box.Add(static_box_szr_right, 0, wx.TOP|wx.ALIGN_RIGHT, 50)
    
    # Building the leftmost box
    leftmost_box.Add(button_back_wgt, 0, wx.ALL|wx.ALIGN_LEFT, 10)
    leftmost_box.Add(static_box_szr_left, 0, wx.ALL|wx.ALIGN_LEFT, 10)
    leftmost_box.Add((-1,-1), proportion=1)
    leftmost_box.Add(leftmost_box_subsizer, 0, wx.ALL|wx.EXPAND, 10)
    
    # Building the leftmost subsizer
    leftmost_box_subsizer.AddMany([
                                 (  start_mode_button_wgt,     wx.TOP|wx.BOTTOM|wx.ALIGN_BOTTOM, 10 ),
                                 (  crossword_mode_button_wgt, wx.TOP|wx.BOTTOM|wx.ALIGN_BOTTOM, 10 ),
                                 (  browse_mode_button_wgt,    wx.TOP|wx.BOTTOM|wx.ALIGN_BOTTOM, 10 )
                                 ])
    
    #Toggle the start mode button
    start_mode_button_wgt.SetValue(True)
    
    # The pLexis logo
    central_box.Add(bitmap_logo_image, 0, wx.ALL|wx.ALIGN_CENTRE, 5)
    # The word card
    central_box.Add(static_box_szr_central, 0, wx.ALL|wx.ALIGN_CENTRE, 5)
    
    # Kick it!
    panel.SetSizer(main_box)
    mainframe.Show()
    app.MainLoop()
    

    【讨论】:

    • 谢谢!它就像魅力一样。只有一个问题:这条线做了什么 leftmost_box.Add((-1,-1), ratio=1) ?
    • 这就是我上面提到的dummy item。它是一个插入到 sizer 中的条目,比例为 1(在 wx.BoxSizer 的主方向上更改其大小)。当最后一项添加带有 wx.EXPAND 标志时,这会将其推到底部
    • 谢谢,现在很清楚了。还有一个问题:如何将最右边的项目(即搜索栏和静态文本)强制到右侧?设置 wx.ALIGN_RIGHT 标志不起作用。
    • 如果在 button_next_wgt 上设置并更改 static_box_szr_right 上的 50 的填充并使其像其他填充一样为 10,则可以。正如我在回答中所说,您确实需要查看 flag 条目。我固定了比例值,但标志条目是我无法猜测的视觉事物。
    • 作为记录,leftmost_box.Add((-1,-1), proportion=1) 是我这样做的老式方式leftmost_box. AddStretchSpacer()(不确定该功能何时添加到 wxpython)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    相关资源
    最近更新 更多