1

我有一些行为奇怪的 wxpython 代码.. 这是 OKAY 代码:

class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title,size=(500, 300))
        self.CreateStatusBar() 
        panel = wx.Panel(self)

        self.srcSizer = wx.BoxSizer(wx.HORIZONTAL)
        srcButton = wx.Button(panel, wx.ID_ANY, "src")
        srcButton.Bind(wx.EVT_BUTTON, self.onSrcButton)
        self.srcSizer.Add(srcButton, 0)
        self.srcTxt = wx.TextCtrl(panel, wx.ID_ANY)
        self.srcSizer.Add(self.srcTxt, 1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=10)

        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.srcSizer, 0 , flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=10)


        panel.SetSizer(self.sizer)
        self.Show(True)

现在当我交换创建状态栏和面板的两行时,它们变成

panel = wx.Panel(self)
self.CreateStatusBar() 

然后在加载窗口时按钮和textctrl重叠,在手动调整窗口大小时将它们恢复到正常位置!

self.CreatStatusBar() 是否必须始终在创建面板或其他东西之前?

谢谢

4

1 回答 1

3

CreateStatusBar()在框架上触发调整大小事件,为状态栏腾出空间。如果面板已创建,则调整其大小以适合框架的客户区域。调整面板大小会触发面板上的调整大小事件,然后如果适用,它将重新计算其布局(大小调整器)。

创建控件(要添加到面板的大小调整器)只需将它们放置在默认位置 (0,0) 及其默认大小。他们将需要布局(大小)更新才能移动到正确的位置。(这就是为什么出现问题时左上角有一堆控件的原因。)

当显示框架时,会触发一个 resize 事件(再次)。但是,如果面板已经适合框架的客户区域,则不会触发面板的调整大小事件,因此不会更新其布局。

即使没有状态栏,您也可以通过创建具有客户区大小的面板来观察这种效果:

panel = wx.Panel(self,size=self.GetClientSize())
#self.CreateStatusBar()

同样,您可以通过将面板的大小设置为其他值来触发更新(一旦显示框架,它将再次调整面板的大小):

# at the end of __init__
panel.SetSize(0,0)

但是,这会造成不必要的调整大小:首先是当您手动SetSize()然后再次在frame.Show(). 有一种更好的方法(如下所示)。

wx 2.8中,这个问题也适用CreateToolBar()wx 2.9.4似乎可以正确处理工具栏。


作为一种解决方法,您可以:

  • 在创建面板之前 设置面板的 sizer 之后创建工具栏/状态栏(需要先将控件添加到 sizer)
  • 设置 sizer 后重新计算面板的布局:

    panel.SetSizer(sizer)
    panel.Layout()
    
于 2012-12-23T18:24:27.637 回答