4

我正在学习wxPython,并且正在尝试编写一个学生信息管理器。我已经编写 CLI 程序很多年了,所以我没有太多制作 GUI 的经验。

首先,我为我的 UI 绘制了一个蓝图。 我的 UI 蓝图

然后,我尝试在 wxPython 中实现它,但 sizer 真的让我发疯了。我以前从未使用过任何类型的sizer!(Visual Basic 是我学习的第一门语言 ^__^)

最后,我写了这段代码:

import wx
from wx.lib import sheet


class Sheet(sheet.CSheet):
    def __init__(self, parent, row, col):
        sheet.CSheet.__init__(self, parent)
        self.row = self.col = 0
        self.SetNumberRows(row)
        self.SetNumberCols(col)

        for i in range(row):
            self.SetRowSize(i, 20)


class ChartPanel(wx.Panel):
    '''This is the panel for the chart, but the still working on it. '''
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)


class MainPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        sizer = wx.GridBagSizer(5, 5)

        # However, just put the chart into main frame.
        chart = ChartPanel(self)
        chart.SetBackgroundColour("blue")

        Students = Sheet(self, 5, 2)
        History = Sheet(self, 2, 2)

        button1 = wx.Button(self, label="Button #1")
        button2 = wx.Button(self, label="Button #2")
        button3 = wx.Button(self, label="Button #3")

        sizer.Add(Students, pos=(0, 0), span=(5, 2), flag=wx.EXPAND)
        sizer.Add(History, pos=(0, 2), span=(2, 2), flag=wx.EXPAND)
        sizer.Add(chart, pos=(2, 2), span=(3, 2), flag=wx.EXPAND)

        sizer.Add(button1, pos=(5, 0), span=(1, 1))
        sizer.Add(button2, pos=(5, 1), span=(1, 1))
        sizer.Add(button3, pos=(5, 2), span=(1, 1))

        sizer.AddGrowableCol(5)
        sizer.AddGrowableRow(5)

        self.SetSizer(sizer)
        self.Fit()


class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="BoxSizer Example")
        panel = MainPanel(self)
        self.Show()

if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

但是这个程序是丑陋和错误的。有人可以教我如何以一种聪明的方式使用sizer,并帮助我修改我的代码吗?

非常感谢!

4

1 回答 1

3

首先,我不得不删除你的AddGrowableColumn()AddGrowableRow()行,因为它们给了我错误。我阅读了这些函数的文档,我认为你不想调用它们(但只有你知道你希望你的 UI 看起来如何)。

实际上,您似乎对 sizers 有很好的掌握。问题是MainPanel不知道 的大小MainFrame,所以你的部分 UI 被切断了。解决这个问题很容易,你有两个选择。

选项 1
MainFrame.__init__()中,放置panel在 sizer 内。这将允许 sizer 根据 的大小设置 的panel大小MainFrame。现在它们的大小之间没有联系。更改将如下所示:

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="BoxSizer Example")
        panel = MainPanel(self)
        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(panel)
        self.SetSizer(sizer) #this allows panel and MainFrame to influence each other's sizes
        self.Show()
        self.Fit()

选项 2
MainFrame中只有 1 个对象,一个MainPanel. 那么为什么不将这两个类合二为一呢?只需将所有代码从MainPane1intoMainFrame然后删除即可MainPanel。重要的部分是MainPanel.__init__()调用SetSizer(). 如果您将该代码移入,MainFrame.__init__()那么您仍然完全按照我在选项 1 中的建议进行操作,但您的课程更少。看起来像这样:

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, title="BoxSizer Example")
        sizer = wx.GridBagSizer(5, 5)

        # However, just put the chart into main frame.
        chart = ChartPanel(self)
        chart.SetBackgroundColour("blue")

        Students = Sheet(self, 5, 2)
        History = Sheet(self, 2, 2)

        button1 = wx.Button(self, label="Button #1")
        button2 = wx.Button(self, label="Button #2")
        button3 = wx.Button(self, label="Button #3")

        sizer.Add(Students, pos=(0, 0), span=(5, 2), flag=wx.EXPAND)
        sizer.Add(History, pos=(0, 2), span=(2, 2), flag=wx.EXPAND)
        sizer.Add(chart, pos=(2, 2), span=(3, 2), flag=wx.EXPAND)

        sizer.Add(button1, pos=(5, 0), span=(1, 1))
        sizer.Add(button2, pos=(5, 1), span=(1, 1))
        sizer.Add(button3, pos=(5, 2), span=(1, 1))

        #I removed these lines because they gave me errors and I don't understand why you needed them
        #sizer.AddGrowableCol(5) 
        #sizer.AddGrowableRow(5)

        self.SetSizer(sizer)
        self.Fit()
        self.Show()

最后,我不喜欢使用wx.GridBagSizer. 我更喜欢使用嵌套wx.BoxSizer对象。我发现我获得了更多的控制权,它使我可以仅从代码中可视化我的 UI 的外观,因为我将 UI 分成更小的块。但是,这是个人喜好问题,您应该使用您理解和熟悉的任何方法。查看您的蓝图,我看到有两列。所以首先我们需要一个sizer来处理这些列。然后,每一列可以分成两行。并且按钮需要一个更大的尺寸来容纳它们。代码如下所示:

def __init__(self, parent):
    wx.Panel.__init__(self, parent)
    mainSizer = wx.BoxSizer(wx.HORIZONTAL) #this will make the columns

    rightSizer = wx.BoxSizer(wx.VERTICAL) #this will be the rows on the right
    # However, just put the chart into main frame.
    chart = ChartPanel(self)
    chart.SetBackgroundColour("blue")
    History = Sheet(self, 2, 2)

    rightSizer.Add(History, 1, wx.EXPAND)
    rightSizer.Add(chart, 1, wx.EXPAND)

    leftSizer = wx.BoxSizer(wx.VERTICAL) #this will be the rows on the left
    Students = Sheet(self, 5, 2)

    buttonSizer = wx.BoxSizer(wx.HORIZONTAL) #this will organize the buttons
    button1 = wx.Button(self, label="Button #1")
    button2 = wx.Button(self, label="Button #2")
    button3 = wx.Button(self, label="Button #3")

    buttonSizer.Add(button1)
    buttonSizer.Add(button2)
    buttonSizer.Add(button3)

    leftSizer.Add(Students, 1, wx.EXPAND)
    leftSizer.Add(buttonSizer)

    mainSizer.Add(leftSizer, 1, wx.EXPAND)
    mainSizer.Add(rightSizer, 1, wx.EXPAND)

    self.SetSizer(mainSizer)
    self.Fit()
于 2012-09-01T02:45:35.643 回答