将来的你
一定会感谢现在拼命努力的自己

wxPython 教程(四): 布局管理

应用包含多个 widgets,这些 widgets  都被放置在容器内,我们必须正确的对 widgets 的位置进行管理,这不是一件容易的事情。在 wxPython 布局 中,可以使用绝对定位或者使用 sizers 对 widgets 进行位置管理。

绝对定位

在 wxPython 布局 时,我们可以对 widgets 在像素水平对 widgets 进行定位,但是这样做的缺点有:

  • 如果我们调整窗口大小时,widget 的尺寸和位置不会随之改变。
  • 在不同的系统上,应用的界面不一致。
  • 修改应用字体会使界面变得混乱。
  • 如果我们决定修改布局,必须重头开始,这非常冗长耗时。

但是有些场景仍然需要绝对定位。比如,小型的测试样例。但是,实际情况是程序员大多会使用 sizers ,它是 wxPython 的布局管理器。

下面的例子中,我们创建一个文本编辑器的框架。在修改窗口大小时,文字输入区域 wx.TextCtrl 的大小不会跟着改变。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# absolute.py
 
importwx
 
classExample(wx.Frame):
   
    def__init__(self, parent, title):
        super(Example,self).__init__(parent, title=title,
            size=(260,180))
             
        self.InitUI()
        self.Centre()
        self.Show()    
         
    defInitUI(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='')
    app.MainLoop()

在上面带锤子中,我们使用绝对坐标放置了一个文本控制区域。

1
wx.TextCtrl(panel, pos=(3,3), size=(250,150))

我们在wx.TextCtrl的构造函数中使用了绝对定位,x=3,y=3,宽度250px,高度150px。

tutorial wxpython-jiaocheng

图:修改大小之前

tutorial wxpython-jiaocheng

图:修改大小之后

使用sizers

使用sizers比使用绝对定位更通用更灵活,可供选择的 sizer 类型有:

  • wx.BoxSizer
  • wx.StaticBoxSizer
  • wx.GridSizer
  • wx.FlexGridSizer
  • wx.GridBagSizer

下面的例子使用了内置(built-in)的 sizer。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# sizer.py
 
importwx
 
classExample(wx.Frame):
   
    def__init__(self, parent, title):
        super(Example,self).__init__(parent, title=title,
            size=(260,180))
             
        self.InitUI()
        self.Centre()
        self.Show()    
         
    defInitUI(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='')
    app.MainLoop()

在这个例子中,没有显式的 sizer 定义。我们把 wx.TextCtrl 放入 wx.Frame,它有一个内置的 sizer,但是只允许放置一个 widget ,多于一个的话会得到混乱的布局。放入的子 widget 占用了所有剩余空间,除去边框、菜单、工具栏和状态栏。

tutorial wxpython-jiaocheng

图:调整大小之前

tutorial wxpython-jiaocheng

图:调整大小之后

wx.BoxSizer

BoxSizer 允许我们按行或者列来排列多个 widget ,同时也允许 sizer 的嵌套,这时的我们可以构造出非常复杂的布局。

1
2
box=wx.BoxSizer(integer orient)
box.Add(wx.Window window, integer proportion=0, integer flag=0, integer border=0)

wx.BoxSizer 的参数 orient 代表方向,可以是 wx.VERTICAL 或者 wx.HORIZONTAL ,代表竖直或水平。通过Add()函数可以添加widgets ,我们详细了解一下其中的参数。

proportion 参数表示在给定的方向中, widget 安装怎么的比例来调整大小。加入我们有三个按钮,对应的 proportion 参数分别为0,1和2。它们被放入一个水平的 wx.BoxSizer 中。在水平方向, proportion 为0的按钮不会改变大小,proportion 为2的按钮会改变为 proportion 为1按钮的两倍大小。

flag 参数可以更具体的定义 widget 在wx.BoxSizer中的行为。通过flag,我们可以控制 widget 之间的距离。我们需要对不同方向的边界进行定义,不同方向之间可以通过竖线符号|组合。可选的方向为:

  • wx.LEFT
  • wx.RIGHT
  • wx.BOTTOM
  • wx.TOP
  • wx.ALL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# border.py
 
importwx
 
classExample(wx.Frame):
   
    def__init__(self, parent, title):
        super(Example,self).__init__(parent, title=title,
            size=(260,180))
             
        self.InitUI()
        self.Centre()
        self.Show()    
         
    defInitUI(self):
     
        panel=wx.Panel(self)
 
        panel.SetBackgroundColour('#4f5049')
        vbox=wx.BoxSizer(wx.VERTICAL)
 
        midPan=wx.Panel(panel)
        midPan.SetBackgroundColour('#ededed')
 
        vbox.Add(midPan,1, wx.EXPAND | wx.ALL,20)
        panel.SetSizer(vbox)
 
 
if__name__=='__main__':
   
    app=wx.App()
    Example(None, title='Border')
    app.MainLoop()

在上面的例子中,我们在 panel 四周设置一些空间。

1
vbox.Add(midPan,1, wx.EXPAND | wx.ALL,20)

如果使用wx.EXPAND标记,widget 将使用所有剩余给它的空间。同样,我们也可以定义 widgets 的对齐方式,可选有以下选项:

  • wx.ALIGN_LEFT
  • wx.ALIGN_RIGHT
  • wx.ALIGN_TOP
  • wx.ALIGN_BOTTOM
  • wx.ALIGN_CENTER_VERTICAL
  • wx.ALIGN_CENTER_HORIZONTAL
  • wx.ALIGN_CENTER

tutorial wxpython-jiaocheng

图:panel四周的边框

Go to class 程序

下面我们通过一个具体的程序详细介绍几个重点信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# gotoclass.py
 
importwx
 
classExample(wx.Frame):
   
    def__init__(self, parent, title):
        super(Example,self).__init__(parent, title=title,
            size=(390,350))
             
        self.InitUI()
        self.Centre()
        self.Show()    
         
    defInitUI(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))
 
        hbox2=wx.BoxSizer(wx.HORIZONTAL)
        st2=wx.StaticText(panel, label='Matching Classes')
        st2.SetFont(font)
        hbox2.Add(st2)
        vbox.Add(hbox2, flag=wx.LEFT | 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='Go To Class')
    app.MainLoop()

布局比较直观:我们创建了竖直的 sizer ,并将5个水平 sizer 放置其中。

1
2
font=wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)
font.SetPointSize(9)

系统默认的字体大小是10,这里显示会过大,我们将其设置为9。

1
2
3
4
vbox.Add(hbox3, proportion=1, flag=wx.LEFT|wx.RIGHT|wx.EXPAND,
 border=10)
 
vbox.Add((-1,25))

我们已经知道我们可以通过结合边框相关的 flag 参数来控制 widgets 之间的距离,但问题是Add()函数只允许设置一个边框数值,这意味着只能给几个方向一样大小的边框。如果你想左右边框设置为10px,而底部设置为25px,通过这种方法是无法做到的。如果我们需要不同的边框值,我们可以增加额外的占位空间(space)。如上面代码的vbox.Add((-1,25)),即是插入space的语句。(-1,25)分别代表宽度和长度,如果某个数值为-1则表明不关注该方向。

1
vbox.Add(hbox5, flag=wx.ALIGN_RIGHT|wx.RIGHT, border=10)

我们在窗口的右侧放置了两个button,实现这一目标需要注意三个参数:proportion、align flag和 wx.EXPAND 标记。proportion 必须设置为0,表明在我们通过鼠标调整窗口大小时,button 不允许更改大小。一定不能设置 wx.EXPAND 标记,button 只允许出现在被分配的位置上。最后必须设置 wx.ALIGN_RIGHT 标记。水平 sizer 中的右对齐可以达到我们的目标。

tutorial wxpython-jiaocheng

图:GoToClass 窗口

wx.GridSizer

wx.GridSizer 即网格布局,它可以在两维的表格中放置 widgets。

1
wx.GridSizer(introws=1,intcols=0,intvgap=0,inthgap=0)

在上面的构造函数中,我们可以定义表格的行列数目,以及单元格之间的横竖间距。

下面的例子中,我们新建了一个计算器的骨架,对wx.GridSizer来说是一个很好的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# calculator.py
 
importwx
 
classExample(wx.Frame):
   
    def__init__(self, parent, title):
        super(Example,self).__init__(parent, title=title,
            size=(300,250))
             
        self.InitUI()
        self.Centre()
        self.Show()    
         
    defInitUI(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=4)
        gs=wx.GridSizer(5,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='Calculator')
    app.MainLoop()

注意下,我们在Bck和Close两个按钮之间放了一个空的wx.StaticText,来达到分隔的目的。

在例子中,我们使用了AddMany()方法,这很便于一次性插入多个widgets。 widgets是安装数组的顺序的插入到表格中的,第一行先被填充,接着是第二行,以此类推。

tutorial wxpython-jiaocheng

图:计算器

wx.FlexGridSizer

这个sizer与wx.GridSizer类似,它同样以两维的表格方式布局widgets,但wx.FlexGridSizer更灵活一些。wx.GridSizer的单元格大小都一样,wx.FlexGridSizer的单元格仅限制每行的单元格高度一致、每列的单元格宽度一致,但无需所有行列的宽高一致。

1
wx.FlexGridSizer(introws=1,intcols=0,intvgap=0,inthgap=0)

rows和cols定义了sizer的行数和列数。vgap和hgap定义了两个方向的widgets之间的间距。

很多时候,开发者需要创建Dialog对话框来接受输入和参数修改,wx.FlexGridSizer就很适合这种情况。开发者可以很容易的使用wx.FlexGridSizer来实现dialog布局。当然wx.GridSizer也可以实现,只是它不太好看,因为所有的单元格大小需要一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# review.py
 
importwx
 
classExample(wx.Frame):
   
    def__init__(self, parent, title):
        super(Example,self).__init__(parent, title=title,
            size=(300,250))
             
        self.InitUI()
        self.Centre()
        self.Show()    
         
    defInitUI(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='Review')
    app.MainLoop()

在上面的例子中我们使用FlexGridSizer创建了一个Review窗口。

1
2
3
hbox=wx.BoxSizer(wx.HORIZONTAL)
...
hbox.Add(fgs, proportion=1, flag=wx.ALL|wx.EXPAND, border=15)

我们创建了一个水平的sizer来在widgets表格周围放置15px的空间。

1
2
fgs.AddMany([(title), (tc1,1, wx.EXPAND), (author),
    (tc2,1, wx.EXPAND), (review,1, wx.EXPAND), (tc3,1, wx.EXPAND)])

我们使用AddMany()添加widgets到sizer中,wx.FlexGridSizer和wx.GridSizer都有这个方法。

1
2
fgs.AddGrowableRow(2,1)
fgs.AddGrowableCol(1,1)

我们让第三行和第二列为可增长的,这是的窗口变化大小时,textCtrl也会跟着增长。前两个textCtrl的宽度会增长,第三个会在两个方向都增长。记得不要忘了添加wx.EXPAND标记。

tutorial wxpython-jiaocheng

图:Review dialog 样例

wx.GridBagSizer

这是 wxPython 布局 中最复杂的sizer,很多开发者会觉得它很难使用。GridBagSizer也并非wxPython独有,其他工具包同样有。虽然它很复杂,但也不是火箭科技,还是可以掌握的:)

wx.GridBagSizer可实现精确定位,widgets还可以跨行或者跨列。构造函数如下:

1
wx.GridBagSizer(integer vgap, integer hgap)

竖直和水平的gap定义了所有子元素之间的空间,我们使用Add()添加元素。

1
2
Add(self, item,tuplepos,tuplespan=wx.DefaultSpan, integer flag=0,
integer border=0, userData=None)

pos定义了位置,左上角的位置为(0,0)。span表示跨几行或者列,比如(3,2)的span表示让一个widget跨3行和2列。flag和border之前在BoxSizer中有讨论。在窗口大小改变时,grid中的widget可以保持大小不变,也可以随窗口改变。如果你想让它增长或者收缩,可以使用下面这两个方法:

1
2
AddGrowableRow(integer row)
AddGrowableCol(integer col)

重命名窗口

在下个例子中,我们将创建一个重命名窗口。它有一个wx.StaticText,一个wx.TextCtrl和两个wx.Button。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# rename.py
 
importwx
 
classExample(wx.Frame):
   
    def__init__(self, parent, title):
        super(Example,self).__init__(parent, title=title,
            size=(320,130))
             
        self.InitUI()
        self.Centre()
        self.Show()    
         
    defInitUI(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=(1,0), 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.AddGrowableCol(1)
        sizer.AddGrowableRow(2)
        panel.SetSizerAndFit(sizer)
     
 
if__name__=='__main__':
   
    app=wx.App()
    Example(None, title='Rename')
    app.MainLoop()

我们需要把这个窗口看做一个大的grid表。

1
2
text=wx.StaticText(panel, label="Rename To")
sizer.Add(text, pos=(0,0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=5)

“Rename To” 文本将被放置在左上角,所以我们设置了(0,0)位置。另外,我们在顶部、左边和底部增加了5px的space空间。

1
2
3
tc=wx.TextCtrl(panel)
sizer.Add(tc, pos=(1,0), span=(1,5),
flag=wx.EXPAND|wx.LEFT|wx.RIGHT, border=5)

wx.TextCtrl从第二行开始,记得我们是从0开始计数的。它占据了一行和5列:(1,5)。我们放置了5px的左右边框空间。

1
2
sizer.Add(buttonOk, pos=(3,3))
sizer.Add(buttonClose, pos=(3,4), flag=wx.RIGHT|wx.BOTTOM, border=5)

我们在第四行放置了2个button。第四行是空的,所有wx.TextCtrl和button之间留有空间。我们把OK按钮放在第四列,close按钮放在第五列。需要注意,一旦我们给一个widget应用了边框,整个行都会受到影响。这是我们没有为OK设置底部边框空间的原因。仔细的读者会发现,我们在两个按钮之间没有放置任何空间,这是因为在wx.GridBagSizer的构造函数中,我们已经设置了所有widgets之间的间隔。

1
2
sizer.AddGrowableCol(1)
sizer.AddGrowableRow(2)

最后需要做的是,让dialog可增长。我们让第二列和第三行可增长,现在可以放大或者缩小窗口来试试看了。你也可以注释掉这两行看看有什么效果。

tutorial wxpython-jiaocheng

图:重命名窗口

New class 样例

下个例子,我们模仿新建一个JDeveloper中的窗口,它主要用来在Java中新建类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
# newclass.py
 
importwx
 
classExample(wx.Frame):
 
    def__init__(self, parent, title):   
        super(Example,self).__init__(parent, title=title,
            size=(450,350))
 
        self.InitUI()
        self.Centre()
        self.Show()    
 
    defInitUI(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('exec.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="Create Java Class")
    app.MainLoop()

这是一个更复杂的布局,我们同时使用了wx.GridBagSizer和wx.StaticBoxSizer。

1
2
3
line=wx.StaticLine(panel)
sizer.Add(line, pos=(1,0), span=(1,5),
 flag=wx.EXPAND|wx.BOTTOM, border=10)

上面的代码创建了一条分隔线,来分隔布局中不同组的widgets。

1
2
3
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)

我们在第一行右侧放了一个wx.StaticBitmap。

1
2
sb=wx.StaticBox(panel, label='Optional Attributes')
boxsizer=wx.StaticBoxSizer(sb, wx.VERTICAL)

wxStaticBoxSizer和wx.BoxSizer类似,但它在sizer周围添加了一个静态的盒子,我们在盒子中放入了check选项。

tutorial wxpython-jiaocheng

图:New class窗口

赞(0) 打赏
声明:本站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,若涉及侵权请及时告知,将会在第一时间删除,联系邮箱:contact@3yyy.top。文章观点不代表本站立场。本站原创内容未经允许不得转载:三叶运维 » wxPython 教程(四): 布局管理
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏

https://beian.miit.gov.cn/