【问题标题】:wxpython wx.Notebook does not get any widthwxpython wx.Notebook 没有得到任何宽度
【发布时间】:2013-01-25 09:21:03
【问题描述】:

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

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

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 的左上角开始)。我已经尝试过wx.BoxSizerwx.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()

【问题讨论】:

    标签: python wxpython


    【解决方案1】:

    我不想给你提供一个完整的解决方案,而是给你一点关于 UI 编程的建议。

    您创建了许多面板却从不设置大小调整器,这让您搞砸了。 在编写 UI 代码之前始终考虑您要创建的小部件的结构(层次结构)。想想他们的布局。然后写下代码,按局部性原则分组:大约需要几行来处理层次结构的一层。

    好的,让我们应用这个原则。顶层的笔记本和底部面板:

    wx.Frame +- wx.NoteBook +- PageNodesPathsTables +- ... +- 底部组

    在这个级别,一切都归结为这四行简单的行:

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

    显然您知道如何正确处理wx.NoteBook。对self.SetSizer 的调用非常重要(在您的代码中不存在),否则框架不知道应该使用哪个尺寸器来布局其子级。
    您要求将其分成两半,非常清楚。智慧之语:不要做超出需要的嵌套。这可能更具可扩展性(并且很容易被推迟),但目前不需要。如果你这样做:

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

    您已经引入了至少一个级别 (self.bottomPanel) 和一个不知道如何布局其子组件的子 (self.bottomGroup)。删除不必要的嵌套,您将摆脱面板创建、sizer 创建、sizer 分配等。折叠它会让你更快地了解它。待办事项:

    • 重写程序的这一部分。摆脱多余的说明。
    • 确保每个面板都有一个 sizer。
    • 在单独的方法中重构菜单创建。
    • Window 构造函数中的参数parent 未使用。修复。
    • 您的示例缺少主要方法、导入等。下次提供SSCCE

    【讨论】:

    • 感谢您提供非常清晰和建设性的帖子。我已经按照您的建议重构了我的代码并更新了我的原始帖子。它工作正常,除了添加到 wx.Frame 的两个小部件现在彼此堆叠。你能说出原因吗?
    • 天哪,我将按钮添加到父级,而不是面板本身。谢谢,我现在对 UI 布局有了更深入的了解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2014-01-22
    • 2021-04-25
    相关资源
    最近更新 更多