一个典型的应用程序是由不同的部件。这些小部件被放进容器部件。一个程序员必须管理应用程序的布局。这不是一项容易的任务。在wxPython我们有两个选择。
*absolute positioning
*sizers
Absolute Positioning绝对位置
程序员指定位置和大小的每个小部件以像素为单位。当你使用绝对定位,你必须了解一些事情。
1.如果你改变窗口大小,大小和位置的一个小部件不改变
2.在各种平台上的应用程序看起来不同
3.更改字体在您的应用程序可能会破坏布局
4.如果你决定改变你的布局,你必须完全重做你的布局,这是繁琐又费时
可能存在的情况下,我们可能使用绝对定位。例如,我的教程。我不想使示例太难了,所以我经常使用绝对定位来解释一个主题。但是最重要的是,在现实世界的程序,程序员使用sizer。
在我们的例子中,我们有一个简单的文本编辑器骨架。如果我们调整窗口大小,因为我们希望wx.TextCtrl的大小不会改变。
''' Created on 2012-7-1 @author: Administrator ''' import wx class Example(wx.Frame): def __init__(self,parent,title): super(Example,self).__init__(parent,title=title,size=(260,180)) self.InitUI() self.Centre() self.Show() def InitUI(self): panel = wx.Panel(self, -1) menuBar = wx.MenuBar() filem = wx.Menu() editm = wx.Menu() helpm = wx.Menu() menuBar.Append(filem,"&File") menuBar.Append(editm,"&Edit") menuBar.Append(helpm,"&Help") self.SetMenuBar(menuBar) wx.TextCtrl(panel,pos=(3,3),size=(250,150)) if __name__ == '__main__': app = wx.App() Example(None,title='Layout1') app.MainLoop()
wx.TextCtrl(panel, pos=(3, 3), size=(250, 150))我们构造的wx.TextCtrl的使用绝对定位。在我们的例子中,我们定位在X = 3,Y = 3的wx.TextCtrl。宽度为250像素,高度为150px。
Using sizers使用sizers
Sizers do address all those issues, we mentioned by absolute positioning. We can choose among these sizers:
我们可以选择下列sizers:
1.wx.BoxSizer
2.wx.StaticBoxSizer
3.wx.GridSizer
4.wx.FlexGridSizer
5.wx.GridBagSizer
import wx class Example(wx.Frame): def __init__(self,parent,title): super(Example,self).__init__(parent,title=title,size=(260,180)) self.InitUI() self.Centre() self.Show() def InitUI(self): menuBar = wx.MenuBar() filem = wx.Menu() editm = wx.Menu() helpm = wx.Menu() menuBar.Append(filem,"&File") menuBar.Append(editm,"&Edit") menuBar.Append(helpm,"&Help") self.SetMenuBar(menuBar) wx.TextCtrl(self) if __name__ == '__main__': app = wx.App() Example(None,title='Layout1') app.MainLoop()
在这个例子中,没有用到sizer。我们wx.Frame的部件放在一个wx.TextCtrl。 wx.Frame的部件有一个特殊的内置SIZER。我们可以把wx.Frame的容器内,只有一个窗口。子部件占据所有的空间.
wx.BoxSizer
This sizer enables us to put several widgets into a row or a column. We can put another sizer into an existing sizer. This way we can create very complex layouts.
sizer可以放置很多部件到行或者行。也可以放置其它sizer。这样我们可以创建非常复杂的界面。
box = wx.BoxSizer(integer orient) box.Add(wx.Window window, integer proportion=0, integer flag = 0, integer border = 0)
比例参数定义的部件,将如何定义的方向改变的比例。假设我们有三个按钮的比例0,1和2。它们被添加成水平wx.BoxSizer。按钮0比例不会改变。按钮比例2比1的水平尺寸比例更将改变两次。
与标志参数可以进一步配置在wx.BoxSizer的小部件的行为。我们可以控制的部件之间的边界。我们添加了一些像素部件之间的空间。为了适用边界,我们需要定义的两侧,将用于边境。我们可以结合| e.g wx.LEFT| wx.BOTTOM。我们可以选择这些标志:
1.wx.LEFT
2.wx.RIGHT
3.wx.BOTTOM
4.wx.TOP
5.wx.ALL
''' Created on 2012-7-2 @author: Administrator ''' import wx class Example(wx.Frame): def __init__(self,parent,title): super(Example,self).__init__(parent,title=title,size=(260,180)) self.InitUI() self.Centre() self.Show() def InitUI(self): panel = wx.Panel(self) panel.SetBackgroundColour('#4f5049') vbox = wx.BoxSizer(wx.VERTICAL) midPan = wx.Panel(panel) midPan.SetBackgroundColour('#ededed') vbox.Add(midPan,2,wx.EXPAND|wx.ALL,40) panel.SetSizer(vbox) if __name__ == '__main__': app = wx.App() Example(None,title="Border") app.MainLoop()
vbox.Add(midPan, 1, wx.EXPAND | wx.ALL, 20)
如果我们使用wx.EXPAND标志,我们的部件将使用所有已分配给它的空间。最后,我们还可以定义我们的部件对齐。我们做了以下标志:
1.wx.ALIGN_LEFT
2.wx.ALIGN_RIGHT
3.wx.ALIGN_TOP
4.wx.ALIGN_BOTTOM
5.wx.ALIGN_CENTER_VERTICAL
6.wx.ALIGN_CENTER_HORIZONTAL
7.wx.ALIGN_CENTER
Go To Class
In the following example we introduce several important ideas.
在接下来的例子中,我们介绍了几种重要的方法。
''' Created on 2012-7-2 @author: Administrator ''' import wx class Example(wx.Frame): def __init__(self,parent,title): super(Example,self).__init__(parent,title=title,size=(500,300)) self.InitUI() self.Centre() self.Show() def InitUI(self): panel = wx.Panel(self) font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT) font.SetPointSize(9) vbox = wx.BoxSizer(wx.VERTICAL) hbox1 = wx.BoxSizer(wx.HORIZONTAL) st1 = wx.StaticText(panel,label='Class Name') st1.SetFont(font) hbox1.Add(st1,flag=wx.RIGHT,border=8) tc = wx.TextCtrl(panel) hbox1.Add(tc,proportion=1) vbox.Add(hbox1,flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP,border=10) vbox.Add((-1,10)) hbox3 = wx.BoxSizer(wx.HORIZONTAL) tc2 = wx.TextCtrl(panel, style=wx.TE_MULTILINE) hbox3.Add(tc2, proportion=1, flag=wx.EXPAND) vbox.Add(hbox3, proportion=1, flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=10) vbox.Add((-1, 25)) hbox4 = wx.BoxSizer(wx.HORIZONTAL) cb1 = wx.CheckBox(panel, label='Case Sensitive') cb1.SetFont(font) hbox4.Add(cb1) cb2 = wx.CheckBox(panel, label='Nested Classes') cb2.SetFont(font) hbox4.Add(cb2, flag=wx.LEFT, border=10) cb3 = wx.CheckBox(panel, label='Non-Project classes') cb3.SetFont(font) hbox4.Add(cb3, flag=wx.LEFT, border=10) vbox.Add(hbox4, flag=wx.LEFT, border=10) vbox.Add((-1, 25)) hbox5 = wx.BoxSizer(wx.HORIZONTAL) btn1 = wx.Button(panel, label='Ok', size=(70, 30)) hbox5.Add(btn1) btn2 = wx.Button(panel, label='Close', size=(70, 30)) hbox5.Add(btn2, flag=wx.LEFT|wx.BOTTOM, border=5) vbox.Add(hbox5, flag=wx.ALIGN_RIGHT|wx.RIGHT, border=10) panel.SetSizer(vbox) if __name__ == '__main__': app = wx.App() Example(None,title="gotoclass") app.MainLoop()
font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT) font.SetPointSize(9)
vbox.Add(hbox3, proportion=1, flag=wx.LEFT|wx.RIGHT|wx.EXPAND, border=10) vbox.Add((-1, 25))
vbox.Add(hbox5, flag=wx.ALIGN_RIGHT|wx.RIGHT, border=10)
wx.GridSizer
wx.GridSizer是一个二维表格,每个表格大小相同。
wx.GridSizer(int rows=1, int cols=0, int vgap=0, int hgap=0)
下边是一个不完美的计算器示例:
''' Created on 2012-7-2 @author: Administrator ''' import wx class Example(wx.Frame): def __init__(self,parent,title): super(Example,self).__init__(parent,title=title,size=(300,250)) self.InitUI() self.Centre() self.Show() def InitUI(self): menubar = wx.MenuBar() fileMenu = wx.Menu() menubar.Append(fileMenu,"&File") self.SetMenuBar(menubar) vbox = wx.BoxSizer(wx.VERTICAL) self.display = wx.TextCtrl(self,style=wx.TE_RIGHT) vbox.Add(self.display,flag=wx.EXPAND|wx.TOP|wx.BOTTOM,border=5) gs = wx.GridSizer(4,4,5,5) gs.AddMany( [(wx.Button(self, label='Cls'), 0, wx.EXPAND), (wx.Button(self, label='Bck'), 0, wx.EXPAND), (wx.StaticText(self), wx.EXPAND), (wx.Button(self, label='Close'), 0, wx.EXPAND), (wx.Button(self, label='7'), 0, wx.EXPAND), (wx.Button(self, label='8'), 0, wx.EXPAND), (wx.Button(self, label='9'), 0, wx.EXPAND), (wx.Button(self, label='/'), 0, wx.EXPAND), (wx.Button(self, label='4'), 0, wx.EXPAND), (wx.Button(self, label='5'), 0, wx.EXPAND), (wx.Button(self, label='6'), 0, wx.EXPAND), (wx.Button(self, label='*'), 0, wx.EXPAND), (wx.Button(self, label='1'), 0, wx.EXPAND), (wx.Button(self, label='2'), 0, wx.EXPAND), (wx.Button(self, label='3'), 0, wx.EXPAND), (wx.Button(self, label='-'), 0, wx.EXPAND), (wx.Button(self, label='0'), 0, wx.EXPAND), (wx.Button(self, label='.'), 0, wx.EXPAND), (wx.Button(self, label='='), 0, wx.EXPAND), (wx.Button(self, label='+'), 0, wx.EXPAND) ]) vbox.Add(gs,proportion=1,flag=wx.EXPAND) self.SetSizer(vbox) if __name__ == '__main__': app = wx.App() Example(None,title="caculator") app.MainLoop()
gs.AddMany( [(wx.Button(self, label='Cls'), 0, wx.EXPAND), ...
wx.FlexGridSizer
这SIZER类似wx.GridSizer。它也有二维表的部件。但它增加了一些灵活性。 wx.GridSizer表格是相同的大小。在wx.FlexGridSizer 所有的行和列的不一定是相同的高度或宽度。
wx.FlexGridSizer(int rows=1, int cols=0, int vgap=0, int hgap=0)
很多时候,开发商要开发用于数据输入和修改的对话框。我觉得这样一个任务wx.FlexGridSizer合适。开发人员可以很容易地建立一个对话窗口,因为约束,每个单元必须具有相同的大小。
''' Created on 2012-7-2 @author: Administrator ''' import wx class Example(wx.Frame): def __init__(self,parent,title): super(Example,self).__init__(parent,title=title,size=(300,250)) self.InitUI() self.Centre() self.Show() def InitUI(self): panel = wx.Panel(self) hbox = wx.BoxSizer(wx.HORIZONTAL) fgs = wx.FlexGridSizer(3,2,9,25) title = wx.StaticText(panel,label='Title:') author = wx.StaticText(panel,label='Author:') review = wx.StaticText(panel,label='Review') tc1 = wx.TextCtrl(panel) tc2 = wx.TextCtrl(panel) tc3 = wx.TextCtrl(panel, style=wx.TE_MULTILINE) fgs.AddMany([(title),(tc1,1,wx.EXPAND),(author), (tc2,1,wx.EXPAND),(review,1,wx.EXPAND),(tc3,1,wx.EXPAND)]) fgs.AddGrowableRow(2,1) fgs.AddGrowableCol(1,1) hbox.Add(fgs,proportion=1,flag=wx.ALL|wx.EXPAND,border=15) panel.SetSizer(hbox) if __name__ == '__main__': app = wx.App() Example(None,title="FlexGridSizer.py") app.MainLoop()
hbox = wx.BoxSizer(wx.HORIZONTAL) ... hbox.Add(fgs, proportion=1, flag=wx.ALL|wx.EXPAND, border=15)
fgs.AddMany([(title), (tc1, 1, wx.EXPAND), (author), (tc2, 1, wx.EXPAND), (review, 1, wx.EXPAND), (tc3, 1, wx.EXPAND)])
fgs.AddGrowableRow(2, 1) fgs.AddGrowableCol(1, 1)
wx.GridBagSizer
在wxPython中最复杂Sizer要属它了。许多程序员发现很难使用。这样sizer是不是只对wxPython的典型,其它语言也有它。即使它是比较复杂,也不难攻克。
wx.GridBagSizer有一个简单的构造:
wx.GridBagSizer(integer vgap, integer hgap)
Add(self, item, tuple pos, tuple span=wx.DefaultSpan, integer flag=0, integer border=0, userData=None)
AddGrowableRow(integer row) AddGrowableCol(integer col)
''' Created on 2012-7-2 @author: Administrator ''' import wx class Example(wx.Frame): def __init__(self,parent,title): super(Example,self).__init__(parent,title=title,size=(320,130)) self.InitUI() self.Centre() self.Show() def InitUI(self): panel = wx.Panel(self) sizer = wx.GridBagSizer(4,4) text = wx.StaticText(panel,label='Rename to') sizer.Add(text,pos=(0,0),flag=wx.TOP|wx.LEFT|wx.BOTTOM,border=5) tc = wx.TextCtrl(panel) sizer.Add(tc,pos=(0,1),span=(1,5),flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=5) buttonOK = wx.Button(panel,label='OK',size=(90,28)) buttonClose = wx.Button(panel,label='Close',size=(90,28)) sizer.Add(buttonOK,pos=(3,3)) sizer.Add(buttonClose,pos=(3,4),flag=wx.RIGHT|wx.BOTTOM,border=5) sizer.AddGrowableRow(2) sizer.AddGrowableCol(1) panel.SetSizerAndFit(sizer) if __name__ == '__main__': app = wx.App() Example(None,title="FlexGridSizer.py") app.MainLoop()
text = wx.StaticText(panel, label="Rename To") sizer.Add(text, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=5)
tc = wx.TextCtrl(panel) sizer.Add(tc, pos=(1, 0), span=(1, 5), flag=wx.EXPAND|wx.LEFT|wx.RIGHT, border=5)
sizer.Add(buttonOk, pos=(3, 3)) sizer.Add(buttonClose, pos=(3, 4), flag=wx.RIGHT|wx.BOTTOM, border=5)
sizer.AddGrowableCol(1) sizer.AddGrowableRow(2)
''' Created on 2012-7-2 @author: Administrator ''' import wx class Example(wx.Frame): def __init__(self,parent,title): super(Example,self).__init__(parent,title=title,size=(450,350)) self.InitUI() self.Centre() self.Show() def InitUI(self): panel = wx.Panel(self) sizer = wx.GridBagSizer(5,5) text1 = wx.StaticText(panel,label="Java Class") sizer.Add(text1, pos=(0,0),flag=wx.TOP|wx.LEFT|wx.BOTTOM,border=15) icon = wx.StaticBitmap(panel,bitmap=wx.Bitmap("exit.png")) sizer.Add(icon,pos=(0,4),flag=wx.TOP|wx.RIGHT|wx.ALIGN_RIGHT,border=5) line = wx.StaticLine(panel) sizer.Add(line,pos=(1,0),span=(1,5),flag=wx.EXPAND|wx.BOTTOM,border=10) text2 = wx.StaticText(panel,label="Name") sizer.Add(text2,pos=(2,0),flag=wx.LEFT,border=10) tc1 = wx.TextCtrl(panel) sizer.Add(tc1,pos=(2,1),span=(1,3),flag=wx.TOP|wx.EXPAND) text3 = wx.StaticText(panel, label="Package") sizer.Add(text3, pos=(3, 0), flag=wx.LEFT|wx.TOP, border=10) tc2 = wx.TextCtrl(panel) sizer.Add(tc2, pos=(3, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND, border=5) button1 = wx.Button(panel, label="Browse...") sizer.Add(button1, pos=(3, 4), flag=wx.TOP|wx.RIGHT, border=5) text4 = wx.StaticText(panel, label="Extends") sizer.Add(text4, pos=(4, 0), flag=wx.TOP|wx.LEFT, border=10) combo = wx.ComboBox(panel) sizer.Add(combo, pos=(4, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND, border=5) button2 = wx.Button(panel, label="Browse...") sizer.Add(button2, pos=(4, 4), flag=wx.TOP|wx.RIGHT, border=5) sb = wx.StaticBox(panel, label="Optional Attributes") boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL) boxsizer.Add(wx.CheckBox(panel, label="Public"), flag=wx.LEFT|wx.TOP, border=5) boxsizer.Add(wx.CheckBox(panel, label="Generate Default Constructor"), flag=wx.LEFT, border=5) boxsizer.Add(wx.CheckBox(panel, label="Generate Main Method"), flag=wx.LEFT|wx.BOTTOM, border=5) sizer.Add(boxsizer, pos=(5, 0), span=(1, 5), flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT , border=10) button3 = wx.Button(panel, label='Help') sizer.Add(button3, pos=(7, 0), flag=wx.LEFT, border=10) button4 = wx.Button(panel, label="Ok") sizer.Add(button4, pos=(7, 3)) button5 = wx.Button(panel, label="Cancel") sizer.Add(button5, pos=(7, 4), span=(1, 1), flag=wx.BOTTOM|wx.RIGHT, border=5) sizer.AddGrowableCol(2) panel.SetSizer(sizer) if __name__ == '__main__': app = wx.App() Example(None,title="Newclass.py") app.MainLoop()
line = wx.StaticLine(panel) sizer.Add(line, pos=(1, 0), span=(1, 5), flag=wx.EXPAND|wx.BOTTOM, border=10)
icon = wx.StaticBitmap(panel, bitmap=wx.Bitmap('exec.png')) sizer.Add(icon, pos=(0, 4), flag=wx.TOP|wx.RIGHT|wx.ALIGN_RIGHT, border=5)
sb = wx.StaticBox(panel, label="Optional Attributes") boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)