2012-08-31 59 views
3

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

首先,我画了我的UI的蓝图。 A blueprint of my UI

然后,我试图让它在wxPython中,但sizers真的让我发疯。我以前从未使用过任何类型的筛选器! (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() 

但这个程序是丑陋和马车。有人可以教我如何以智能的方式使用sizers,并帮助我修改我的代码吗?

非常感谢!

+0

我知道你的感受,所以首先现在很多很多人都明白你彻底沮丧......了解施胶剂我试着阅读关于sizer的许多文档,但是我最终通过将它想像为HTML中的CSS来获得它,所以请阅读这个http://www.htmldog。com/guides/cssbeginner/margins/AND后面的页面,我发现它很好地解释了CSS,它和sizers一样是一个布局模型....我简直不敢相信我记得那个链接有一段时间是我读的它猜测它表明它是很好的营销。 – Zimm3r

回答

2

首先,我不得不删除你的​​和AddGrowableRow()行,因为他们给了我错误。我为这些功能读了documentation,我不认为你想给他们打电话(但只有你知道你想如何看你的UI)。

你实际上似乎对sizer有很好的把握。问题是MainPanel不知道MainFrame的大小,所以部分UI被切断。解决这个问题很简单,你有两个选择。

选项1
MainFrame.__init__(),放置panel施胶机的内部。这将允许sizer根据MainFrame的大小设置panel的大小。现在它们的尺寸之间没有关系。这种变化将是这样的:

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。那么为什么不把这两个类合并为一个呢?只需将MainPane1中的所有代码添加到MainFrame,然后删除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() 
+0

谢谢。但是我仍然有两个问题:1.当用户调整窗口大小时,我希望窗口小部件更改大小。 2.框架中的三个按钮占用太多空间,我希望它们看起来与我的蓝图相似。 –

+0

然后你需要使按钮变小。创建按钮时,必须设置按钮的大小。除此之外,'wx.EXPAND'标志应该表示其他所有内容都随窗口调整大小。 – acattle

+0

谢谢。嵌套sizers非常有用! –