1

我正在尝试使用 wx.Notebook 创建一个项目工具,顶部带有选项卡,底部有一个常规面板。底部面板应独立于笔记本,并且在选项卡更改时不会更改。当我只添加笔记本时,笔记本本身可以正常工作,但是当我还添加我的底部面板(扩展的 wx.Panel)时,笔记本会被挤压,如图所示。

我有一个窗口面板,并将笔记本和底部面板(称为 BottomGroup,扩展 wx.Panel)添加到单独的面板中。任何人都可以发现问题吗?也许与sizer有关?我的窗口是这样的(没关系标签是错误的):

class Window(wx.Frame):

def __init__(self, parent, title):

    wx.Frame.__init__(self, None, wx.ID_ANY, title)
    self.InitUI()


def InitUI(self):    

    menuBar = wx.MenuBar()
    menu = wx.Menu()
    menu_load = menu.Append(wx.ID_OPEN, 'Open', 'Open project')
    menu_save = menu.Append(wx.ID_SAVE, 'Save', 'Save project')
    menu_save_as = menu.Append(wx.ID_SAVEAS, 'Save as', 'Save project as')
    menu_exit = menu.Append(wx.ID_EXIT, 'Quit', 'Quit application')
    menuBar.Append(menu, '&File')
    self.SetMenuBar(menuBar)

    mainPanel = wx.Panel(self)

    self.noteBookPanel = wx.Panel(mainPanel)
    self.notebook = wx.Notebook(self.noteBookPanel)
    self.bottomPanel = wx.Panel(mainPanel)
    self.bottomGroup = BottomGroup(self.bottomPanel)

    mainSizer = wx.BoxSizer(wx.VERTICAL)

    self.pageNodePathsTables = PageNodesPathsTables(self.notebook)
    self.pageEscapeCriteria = PageEscapeCriteria(self.notebook)
    self.pageFileHandling = PageFileHandling(self.notebook)

    self.notebook.AddPage(self.pageNodePathsTables, "Define Paths and Nodes")
    self.notebook.AddPage(self.pageEscapeCriteria, "Define Escape Criteria")
    self.notebook.AddPage(self.pageFileHandling, "File Handling")

    mainSizer.Add(self.noteBookPanel,1,wx.TOP)
    mainSizer.Add(self.bottomGroup,1,wx.BOTTOM)

    self.Bind(wx.EVT_MENU, self.onSave, menu_save)
    self.Bind(wx.EVT_MENU, self.onLoad, menu_load)
    self.Bind(wx.EVT_MENU, self.OnQuit, menu_exit)

    self.SetDimensions(WindowOpenX,WindowOpenY,WindowWidth,WindowHeight) 
    self.Show(True)

更新:

我已将代码重构为此(仅显示重构部分):

    self.notebook = wx.Notebook(self)
    self.bottomGroup = BottomGroup(self)

    self.setupMenu()

    #frameSizer = wx.GridBagSizer(rowGap,columnGap)
    #frameSizer.Add(self.notebook,pos=(0,0), span=(1,1),
    #              flag=wx.LEFT|wx.TOP|wx.EXPAND, border = 5)
    #frameSizer.Add(self.bottomGroup,pos=(1,0), span=(1,1),
    #              flag=wx.LEFT|wx.BOTTOM|wx.EXPAND, border = 5)

    frameSizer = wx.BoxSizer(wx.VERTICAL)
    frameSizer.Add(self.notebook, 2, wx.EXPAND)
    frameSizer.Add(self.bottomGroup,0)
    self.SetSizer(frameSizer)

其中self.setupMenu()定义为:

def setupMenu(self):
    self.pageNodePathsTables = PageNodesPathsTables(self.notebook)
    self.pageEscapeCriteria = PageEscapeCriteria(self.notebook)
    self.pageFileHandling = PageFileHandling(self.notebook)
    self.pagePlotHistoryData = PagePlotHistoryData(self.notebook)
    self.pageCalculateEscape = PageCalculateEscape(self.notebook)

    self.notebook.AddPage(self.pageNodePathsTables, "Define Paths and Nodes")
    self.notebook.AddPage(self.pageEscapeCriteria, "Define Escape Criteria")
    self.notebook.AddPage(self.pageFileHandling, "File Handling")
    self.notebook.AddPage(self.pagePlotHistoryData, "Plot History Data")
    self.notebook.AddPage(self.pageCalculateEscape, "Calculate Escape")

这比上面的代码更清晰、更容易。它工作正常,除了bottomGroup现在堆叠在notebook(即两个元素都从 wx.Frame 的左上角开始)。我已经尝试了 thewx.BoxSizer和 the wx.GridBagLayout(如上所述)。你对这个问题有什么建议吗?

我的 BottomGroup 定义如下:

class BottomGroup(wx.Panel):

def __init__(self,parent):
    wx.Panel.__init__(self,parent)
    panelSizer = wx.GridBagSizer(rowGap,columnGap)

    btnSaveProject = wx.Button(parent, label="Save project", size=(100,50))
    btnLoadProject = wx.Button(parent, label="Open project", size=(100,50))

    panelSizer.Add(btnSaveProject, pos=(0,0), span=(1,1),
                             flag=wx.EXPAND|wx.LEFT, border = borderWidth)
    panelSizer.Add(btnLoadProject, pos=(0,1), span=(1,1),
                             flag=wx.EXPAND|wx.LEFT, border = borderWidth)

    self.SetSizer(panelSizer)

我的主要方法是这样的:

if __name__ == '__main__':
    app = wx.App()
    Window(None, WindowHeader)
    app.MainLoop()
4

1 回答 1

1

I don't want to provide you with a full solution, but rather a little advice on UI programming.

You screwed up by creating to many panels and never setting a sizer. Before writing UI code always think of the structure (hierarchy) of widgets you want to create. Think of their layout. Then write down the code, grouped by principle of locality: approximately one level of the hierarchy should be handled in a few lines.

Good, let's apply the principle. Notebook and bottom panel at top level:

wx.Frame  
 +- wx.NoteBook
     +- PageNodesPathsTables
     +- ...
 +- BottomGroup

At this level, everything comes down to these four, simple lines:

sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.notebook, 2, wx.EXPAND)
sizer.Add(self.bottomPanel, 0)
self.SetSizer(sizer)

Obviously you know how to handle a wx.NoteBook properly. Very important is the call to self.SetSizer (non-existent in your code), because otherwise the frame has no idea which sizer it should use for layouting its children.
You demands about the partitioning in two halves where pretty clear. Words of wisdom: Don't do more nesting than needed. This might be more extensible (and can easily be postponed), but at the moment it's not needed. If you do something like this:

self.bottomPanel = wx.Panel(mainPanel)
self.bottomGroup = BottomGroup(self.bottomPanel)

You have introduced at least one level (self.bottomPanel) with a single child (self.bottomGroup) that has no clue how to layout its child components. Erase the unnecessary nesting, and you will get rid of panel creation, sizer creation, sizer assignment, and so on. Collapsing it will get you a quicker overview. Todo:

  • Rewrite this section of you program. Get rid of superfluous instructions.
  • Make sure every panel has a sizer.
  • Refactor menu creation in a separate method.
  • Parameter parent in the Window constructor is unused. Fix.
  • Your example was missing a main method, imports, etc. Next time, supply an SSCCE.
于 2013-01-25T10:16:48.670 回答