wxPython StaticText赢得';文本更改时不调整大小

wxPython StaticText赢得';文本更改时不调整大小,python,wxpython,Python,Wxpython,我的wxPython代码有一些大小问题。我有一条StaticText帮助消息,可以显示也可以隐藏,该消息需要根据用户模式进行更改 默认情况下,包含StaticText的BoxSizer在第一次显示StaticText时会正确地假定其大小,但在StaticText内容更改时不会重新调整大小 我的初始代码如下所示(对于上下文,完整代码在我文章的末尾): 然后我尝试手动设置大小: self.msg_text_size = (500, 100) self.msg_text

我的wxPython代码有一些大小问题。我有一条StaticText帮助消息,可以显示也可以隐藏,该消息需要根据用户模式进行更改

默认情况下,包含StaticText的BoxSizer在第一次显示StaticText时会正确地假定其大小,但在StaticText内容更改时不会重新调整大小

我的初始代码如下所示(对于上下文,完整代码在我文章的末尾):

然后我尝试手动设置大小:

        self.msg_text_size = (500, 100)
        self.msg_text = wx.StaticText(self.panel, label=self.default_msg_text,
                                      style=wx.TE_CENTER | wx.EXPAND,
                                      name='help msg text',
                                      size=self.msg_text_size)
        self.help_msg_boxsizer.Add(self.msg_text, flag=wx.EXPAND)
        self.help_msg_boxsizer.ShowItems(False)
然后使用:

    self.msg_text.SetSize(new_size)
    # or
    self.help_msg_boxsizer.GetStaticBox.SetSize(new_size)
但这两条线似乎都不起作用。取而代之的是,无论发生什么情况,初始尺寸(500100)似乎仍然会被使用

我认为设置大小提示可能会有所帮助,但似乎没有效果:

    self.help_msg_boxsizer.SetSizeHints()
最后,wx.EXPAND的存在与否似乎没有什么区别

总而言之:我想做的是适当地将
self.msg_text
重新调整到显示时所需的最小大小。我怎样才能做到这一点

下面是运行我的示例的完整代码:

import wx
import sys


class GridFrame(wx.Frame):

    def __init__(self, frame_name="grid frame",
                 panel_name="grid panel", parent=None):
        title = 'Edit {} data'.format(panel_name)
        super(GridFrame, self).__init__(parent=parent, id=wx.ID_ANY,
                                        name=frame_name, title=title)
        self.remove_cols_mode = False
        self.panel = wx.Panel(self, name=panel_name)#, size=wx.GetDisplaySize())
        self.grid_type = str(panel_name)
        self.InitUI()


    ## Initialization functions
    def InitUI(self):
        """
        initialize window
        """
        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
        set1 = []
        ## btns set 1
        for btn_name in ['btn1']:
            btn = wx.Button(self.panel, label=btn_name, name=btn_name)
            set1.append((btn))
        self.remove_cols_button = wx.Button(self.panel, label="Remove columns",
                                            name='remove_cols_btn')
        self.Bind(wx.EVT_BUTTON, self.on_remove_cols, self.remove_cols_button)

        ## Help message and button
        # button
        self.toggle_help_btn = wx.Button(self.panel, id=-1, label="Show help",
                                         name='toggle_help_btn')
        self.Bind(wx.EVT_BUTTON, self.toggle_help, self.toggle_help_btn)
        # message
        self.help_msg_boxsizer = wx.StaticBoxSizer(wx.StaticBox(self.panel, -1, name='help_msg_boxsizer'),
                                                   wx.VERTICAL)
        self.default_msg_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec pulvinar, massa sit amet congue facilisis, augue nisl vehicula nulla, vel posuere ligula metus eu sapien. Nam vitae mauris nec turpis congue eleifend. Ut accumsan lorem risus, vitae scelerisque mi viverra at. In sit amet purus pretium, ultricies neque eget, ultricies enim. Aenean dignissim ornare mattis. Sed vitae consequat urna, et congue neque."
        self.msg_text_size = (500, 100)
        self.msg_text = wx.StaticText(self.panel, label=self.default_msg_text,
                                      style=wx.TE_CENTER | wx.EXPAND,
                                      name='help msg text',
                                      size=self.msg_text_size)
        self.help_msg_boxsizer.Add(self.msg_text, flag=wx.EXPAND)
        self.help_msg_boxsizer.SetSizeHints(self)
        self.help_msg_boxsizer.ShowItems(False)

        ## Add content to sizers
        self.hbox = wx.BoxSizer(wx.HORIZONTAL)
        vbox1 = wx.StaticBoxSizer(wx.StaticBox(self.panel, -1, label='Vbox1'), wx.VERTICAL)

        for btn in set1:
            vbox1.Add(btn, flag=wx.ALL, border=5)
        vbox1.Add(self.remove_cols_button)
        self.hbox.Add(vbox1, flag=wx.ALL, border=5)

        # add "grid"
        self.grid_box = wx.StaticBoxSizer(wx.StaticBox(self.panel, -1, name='grid container'), wx.VERTICAL)
        filler = wx.StaticBox(self.panel, wx.ID_ANY, "FillerStaticBox", size=(500, 200))
        self.grid_box.Add(filler, 1, flag=wx.ALL|wx.EXPAND, border=5)
        # final layout, set size
        self.main_sizer.Add(self.hbox, flag=wx.ALL|wx.ALIGN_CENTER|wx.SHAPED, border=20)
        self.main_sizer.AddSpacer(20)
        self.main_sizer.Add(self.toggle_help_btn, .5,
                            flag=wx.BOTTOM|wx.ALIGN_CENTRE|wx.SHAPED,
                            border=5)
        self.main_sizer.Add(self.help_msg_boxsizer, .5,
                            flag=wx.BOTTOM|wx.ALIGN_CENTRE|wx.SHAPED,
                            border=10)
        self.main_sizer.AddSpacer(10)

        self.main_sizer.Add(self.grid_box, 2, flag=wx.ALL|wx.ALIGN_CENTER|wx.EXPAND, border=10)
        self.panel.SetSizer(self.main_sizer)
        self.panel_sizer = wx.BoxSizer(wx.VERTICAL)
        self.panel_sizer.Add(self.panel, 1)
        self.SetSizer(self.panel_sizer)
        self.panel_sizer.Fit(self)
        self.Centre()
        self.Show()


    def do_fit(self, event, min_size=None):
        """
        Re-fit the window to the size of the content.
        """
        if event:
            event.Skip()
        self.panel_sizer.Fit(self)
        self.Centre()
        return

    def toggle_help(self, event, mode=None):
        """
        Show/hide help message on help button click.
        """
        # if mode == 'open', show no matter what.
        # if mode == 'close', close.  otherwise, change state
        btn = self.toggle_help_btn
        shown = self.help_msg_boxsizer.GetStaticBox().IsShown()

        # if mode is specified, do that mode
        if mode == 'open':
            self.msg_text.SetSize(self.msg_text_size)
            self.help_msg_boxsizer.GetStaticBox().SetSize(self.msg_text_size)
            #self.help_msg_boxsizer.Fit(self.msg_text)
            self.help_msg_boxsizer.ShowItems(True)
            btn.SetLabel('Hide help')
        elif mode == 'close':
            self.help_msg_boxsizer.ShowItems(False)
            btn.SetLabel('Show help')
        # otherwise, simply toggle states
        else:
            if shown:
                self.help_msg_boxsizer.ShowItems(False)
                btn.SetLabel('Show help')
            else:
                self.msg_text.SetSize(self.msg_text_size)
                self.help_msg_boxsizer.GetStaticBox().SetSize(self.msg_text_size)
                #self.help_msg_boxsizer.Fit(self.msg_text)
                self.help_msg_boxsizer.ShowItems(True)
                btn.SetLabel('Hide help')

        self.do_fit(None)


    ##  Events

    def on_remove_cols(self, event):
        """
        enter 'remove columns' mode
        """
        self.remove_cols_mode = True
        self.remove_cols_button.SetLabel("end delete column mode")
        self.remove_cols_button.SetSize(self.remove_cols_button.GetBestSize())
        # change button to exit the delete columns mode
        self.Unbind(wx.EVT_BUTTON, self.remove_cols_button)
        self.Bind(wx.EVT_BUTTON, self.exit_col_remove_mode, self.remove_cols_button)
        # then make some visual changes
        self.msg_text_size = (50, 50)
        self.msg_text.SetLabel("Remove grid columns: click on a column header to delete it.Required headers for {}s may not be deleted.".format(self.grid_type))
        self.toggle_help(event=None, mode='open')
        self.grid_box.GetStaticBox().SetWindowStyle(wx.DOUBLE_BORDER)

    def exit_col_remove_mode(self, event):
        """
        go back from 'remove cols' mode to normal
        """
        # close help messge
        self.toggle_help(event=None, mode='close')
        # update mode
        self.remove_cols_mode = False
        self.grid_box.GetStaticBox().SetWindowStyle(wx.DEFAULT)
        self.msg_text.SetLabel(self.default_msg_text)
        self.msg_text_size = (500, 150)
        self.help_msg_boxsizer.Fit(self.help_msg_boxsizer.GetStaticBox())
        self.toggle_help(None, mode='close')
        # re-bind self.remove_cols_button
        self.Bind(wx.EVT_BUTTON, self.on_remove_cols, self.remove_cols_button)
        self.remove_cols_button.SetLabel("Remove columns")
        self.do_fit(None)


if __name__ == "__main__":
    app = wx.App()
    frame = GridFrame()
    if '-i' in sys.argv:
        import wx.lib.inspection
        wx.lib.inspection.InspectionTool().Show()
    app.MainLoop()

您不应该需要这些,因为当文本发生更改时,只需在父级或层次结构上的一个大小调整器上调用Layout就足够了

此外,我看到您在将
帮助\u msg\u boxsizer
添加到
主\u sizer
时设置了
wx.SHAPED
标志。这告诉父大小调整器保持项目第一次添加到大小调整器时具有的相同纵横比,这可能是保持该大小调整器和静态文本的大小不超过0像素高的原因


最后,在几个地方使用的比例值为.5。这个参数是一个整数,所以它只会被截断为零,不会做你希望它做的事情。比例的工作方式是,sizer中比例值的总和用于计算自由空间的划分方式。例如,如果长方体大小调整器具有比例为1、1、2的项目,则前两个项目的可用空间分别为25%,第三个项目的可用空间为50%。

您不需要这些,因为在更改文本时,只需调用父级或层次结构上的一个大小调整器就足够了

此外,我看到您在将
帮助\u msg\u boxsizer
添加到
主\u sizer
时设置了
wx.SHAPED
标志。这告诉父大小调整器保持项目第一次添加到大小调整器时具有的相同纵横比,这可能是保持该大小调整器和静态文本的大小不超过0像素高的原因

最后,在几个地方使用的比例值为.5。这个参数是一个整数,所以它只会被截断为零,不会做你希望它做的事情。比例的工作方式是,sizer中比例值的总和用于计算自由空间的划分方式。例如,如果长方体大小调整器的项目比例为1、1、2,则前两个项目的可用空间分别为25%,第三个项目的可用空间为50%

import wx
import sys


class GridFrame(wx.Frame):

    def __init__(self, frame_name="grid frame",
                 panel_name="grid panel", parent=None):
        title = 'Edit {} data'.format(panel_name)
        super(GridFrame, self).__init__(parent=parent, id=wx.ID_ANY,
                                        name=frame_name, title=title)
        self.remove_cols_mode = False
        self.panel = wx.Panel(self, name=panel_name)#, size=wx.GetDisplaySize())
        self.grid_type = str(panel_name)
        self.InitUI()


    ## Initialization functions
    def InitUI(self):
        """
        initialize window
        """
        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
        set1 = []
        ## btns set 1
        for btn_name in ['btn1']:
            btn = wx.Button(self.panel, label=btn_name, name=btn_name)
            set1.append((btn))
        self.remove_cols_button = wx.Button(self.panel, label="Remove columns",
                                            name='remove_cols_btn')
        self.Bind(wx.EVT_BUTTON, self.on_remove_cols, self.remove_cols_button)

        ## Help message and button
        # button
        self.toggle_help_btn = wx.Button(self.panel, id=-1, label="Show help",
                                         name='toggle_help_btn')
        self.Bind(wx.EVT_BUTTON, self.toggle_help, self.toggle_help_btn)
        # message
        self.help_msg_boxsizer = wx.StaticBoxSizer(wx.StaticBox(self.panel, -1, name='help_msg_boxsizer'),
                                                   wx.VERTICAL)
        self.default_msg_text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec pulvinar, massa sit amet congue facilisis, augue nisl vehicula nulla, vel posuere ligula metus eu sapien. Nam vitae mauris nec turpis congue eleifend. Ut accumsan lorem risus, vitae scelerisque mi viverra at. In sit amet purus pretium, ultricies neque eget, ultricies enim. Aenean dignissim ornare mattis. Sed vitae consequat urna, et congue neque."
        self.msg_text_size = (500, 100)
        self.msg_text = wx.StaticText(self.panel, label=self.default_msg_text,
                                      style=wx.TE_CENTER | wx.EXPAND,
                                      name='help msg text',
                                      size=self.msg_text_size)
        self.help_msg_boxsizer.Add(self.msg_text, flag=wx.EXPAND)
        self.help_msg_boxsizer.SetSizeHints(self)
        self.help_msg_boxsizer.ShowItems(False)

        ## Add content to sizers
        self.hbox = wx.BoxSizer(wx.HORIZONTAL)
        vbox1 = wx.StaticBoxSizer(wx.StaticBox(self.panel, -1, label='Vbox1'), wx.VERTICAL)

        for btn in set1:
            vbox1.Add(btn, flag=wx.ALL, border=5)
        vbox1.Add(self.remove_cols_button)
        self.hbox.Add(vbox1, flag=wx.ALL, border=5)

        # add "grid"
        self.grid_box = wx.StaticBoxSizer(wx.StaticBox(self.panel, -1, name='grid container'), wx.VERTICAL)
        filler = wx.StaticBox(self.panel, wx.ID_ANY, "FillerStaticBox", size=(500, 200))
        self.grid_box.Add(filler, 1, flag=wx.ALL|wx.EXPAND, border=5)
        # final layout, set size
        self.main_sizer.Add(self.hbox, flag=wx.ALL|wx.ALIGN_CENTER|wx.SHAPED, border=20)
        self.main_sizer.AddSpacer(20)
        self.main_sizer.Add(self.toggle_help_btn, .5,
                            flag=wx.BOTTOM|wx.ALIGN_CENTRE|wx.SHAPED,
                            border=5)
        self.main_sizer.Add(self.help_msg_boxsizer, .5,
                            flag=wx.BOTTOM|wx.ALIGN_CENTRE|wx.SHAPED,
                            border=10)
        self.main_sizer.AddSpacer(10)

        self.main_sizer.Add(self.grid_box, 2, flag=wx.ALL|wx.ALIGN_CENTER|wx.EXPAND, border=10)
        self.panel.SetSizer(self.main_sizer)
        self.panel_sizer = wx.BoxSizer(wx.VERTICAL)
        self.panel_sizer.Add(self.panel, 1)
        self.SetSizer(self.panel_sizer)
        self.panel_sizer.Fit(self)
        self.Centre()
        self.Show()


    def do_fit(self, event, min_size=None):
        """
        Re-fit the window to the size of the content.
        """
        if event:
            event.Skip()
        self.panel_sizer.Fit(self)
        self.Centre()
        return

    def toggle_help(self, event, mode=None):
        """
        Show/hide help message on help button click.
        """
        # if mode == 'open', show no matter what.
        # if mode == 'close', close.  otherwise, change state
        btn = self.toggle_help_btn
        shown = self.help_msg_boxsizer.GetStaticBox().IsShown()

        # if mode is specified, do that mode
        if mode == 'open':
            self.msg_text.SetSize(self.msg_text_size)
            self.help_msg_boxsizer.GetStaticBox().SetSize(self.msg_text_size)
            #self.help_msg_boxsizer.Fit(self.msg_text)
            self.help_msg_boxsizer.ShowItems(True)
            btn.SetLabel('Hide help')
        elif mode == 'close':
            self.help_msg_boxsizer.ShowItems(False)
            btn.SetLabel('Show help')
        # otherwise, simply toggle states
        else:
            if shown:
                self.help_msg_boxsizer.ShowItems(False)
                btn.SetLabel('Show help')
            else:
                self.msg_text.SetSize(self.msg_text_size)
                self.help_msg_boxsizer.GetStaticBox().SetSize(self.msg_text_size)
                #self.help_msg_boxsizer.Fit(self.msg_text)
                self.help_msg_boxsizer.ShowItems(True)
                btn.SetLabel('Hide help')

        self.do_fit(None)


    ##  Events

    def on_remove_cols(self, event):
        """
        enter 'remove columns' mode
        """
        self.remove_cols_mode = True
        self.remove_cols_button.SetLabel("end delete column mode")
        self.remove_cols_button.SetSize(self.remove_cols_button.GetBestSize())
        # change button to exit the delete columns mode
        self.Unbind(wx.EVT_BUTTON, self.remove_cols_button)
        self.Bind(wx.EVT_BUTTON, self.exit_col_remove_mode, self.remove_cols_button)
        # then make some visual changes
        self.msg_text_size = (50, 50)
        self.msg_text.SetLabel("Remove grid columns: click on a column header to delete it.Required headers for {}s may not be deleted.".format(self.grid_type))
        self.toggle_help(event=None, mode='open')
        self.grid_box.GetStaticBox().SetWindowStyle(wx.DOUBLE_BORDER)

    def exit_col_remove_mode(self, event):
        """
        go back from 'remove cols' mode to normal
        """
        # close help messge
        self.toggle_help(event=None, mode='close')
        # update mode
        self.remove_cols_mode = False
        self.grid_box.GetStaticBox().SetWindowStyle(wx.DEFAULT)
        self.msg_text.SetLabel(self.default_msg_text)
        self.msg_text_size = (500, 150)
        self.help_msg_boxsizer.Fit(self.help_msg_boxsizer.GetStaticBox())
        self.toggle_help(None, mode='close')
        # re-bind self.remove_cols_button
        self.Bind(wx.EVT_BUTTON, self.on_remove_cols, self.remove_cols_button)
        self.remove_cols_button.SetLabel("Remove columns")
        self.do_fit(None)


if __name__ == "__main__":
    app = wx.App()
    frame = GridFrame()
    if '-i' in sys.argv:
        import wx.lib.inspection
        wx.lib.inspection.InspectionTool().Show()
    app.MainLoop()