实战wxPython:011 - 布局管理之网格布局

在wxPython中提供多种网格布局 wx.GridSizer,wx.FlexGridSizer和wx.GridBagSizer, 它们都提供在一个二维表格中进行布局的功能。在wx.GridSizer布局中,表格中的每个单元格都具有相同的尺寸,而wx.FlexGridSizer则具有更灵活的布局。Wx.GirdBagSizer则在wx.FlexGridSizer之上提供了更多的增强功能。

一、wx.GridSizer

wx.GridSizer提供基本的网格布局功能,其继承关系如图1所示:

 图1:wx.GridSizer继承关系图

GridSizer构造函数如下:

wx.GridSizer(rows, columns, vgap, hgap):

参数:rows定义GridSizer的行数;

cols 定义GridSizer的列数;

vgap 定义垂直方向上行间距;

hgap 定义水平方向上列间距。

wx.GridSizer常用函数有:

  • Add() 在网格中添加一个控件;
  • AddMany() 在网格中添加多个控件;
  • SetRows() 设置Sizer的行数;
  • GetRows() 获得Sizer的行数;
  • SetCols() 设置Sizer的列数;
  • GetCols() 获得Sizer的列数;
  • SetVCap() 设置单元格之间的垂直间隔(像素);
  • GetVCap() 获得单元格自建的垂直间隔;
  • SetHCap() 设置单元格之间的水平间隔(像素);
  • GetHCap() 获得单元格自建的水平间隔。

二、wx.GridSizer示例

下面的代码演示了使用wx.GrideSizer的AddMany()方法构建一个简单的计算器界面,可以看出,其中的控件按行依次填充,首先填满第一列,然后第二列,依次类推。完整代码如下:

import wx

#使用wx.GridSizer实现一个简单的网格布局
class Example(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(Example, self).__init__(*args, **kwargs)
        
        self.SetTitle('实战wxPython: 计算器')
        self.SetSize(400, 300)
        
        self.InitUi()
        
        self.Centre()
        
    def InitUi(self):
        
        #设置应用退出菜单
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        
        miExit = wx.MenuItem(fileMenu, wx.ID_EXIT, '退出(&Q)\tCtrl+Q')
        fileMenu.Append(miExit)   
        #绑定菜单项的行为
        self.Bind(wx.EVT_MENU, self.OnQuit, miExit)
        
        menubar.Append(fileMenu, '文件(&F)')
        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)
        
        
    def OnQuit(self, e):
        self.Close()
        
def main():
    app = wx.App()
    window = Example(None)
    window.Show()
    app.MainLoop()
    
if __name__ == '__main__':
    main()

上述代码的运行结果如图2所示:

 图2:GridSizer布局演示

三、wx.FlexGridSizer

wx.FlexGridSizer继承自wx.GriderSizer,它提供了比wx.GridSizer更灵活的网格布局方法,除与wx.GridSizer相同功能之外,还增加以下一些功能 :

  • 每行和每列可以有各自的尺寸;
  • 在默认情况下,对尺寸大小进行调节时,会改变行和列的整体尺寸,在FlexGriderSizer中,可以指定某行或者某列的尺寸进行调节;
  • 可以在行和列两个方向进行灵活调整,可以为指定个别子元素指定比列量,并且可以指定固定方向上的调整行为。

wx.FlexGridSizer的常用函数有:

  • AddGrowableCol(idx, proportion=0) 设定索引为idx的列为可增长列;
  • AddGrowableRow(idx, proportion=0) 设定索引为idx的行为可增长行。

参数:proportion=0 为默认,表示所有的可增长行或列 按照同比列缩放。如果要指定不一样的缩放比例,那么需要手动设置proportion 值。例如,如 果你有两个尺寸可调整的行,并且它们的proportion分别是2和1,那么这第一个行将得到新空间的2/3,第二行将得到 1/3。

wx.FlexGridSizer的继承关系如图3所示:

 图3:wx.FlexGridSizer继承关系图

四、 wx.FlexGridSizer示例

下面的代码演示了如何使用FlexGridSizer来进行布局:

# 演示wx.FlexGridSizer布局

import wx

class SampleFlexGridSizer(wx.Frame):
    def __init__(self, parent, title):
        super(SampleFlexGridSizer, self).__init__(parent, title=title)

        self.InitUi()
        self.Centre()

    def InitUi(self):
        panel = wx.Panel(self)

        hBox = wx.BoxSizer(wx.HORIZONTAL)

        fgs = wx.FlexGridSizer(3, 2, 9, 25)

        title = wx.StaticText(panel, label="标题")
        author = wx.StaticText(panel, label="作者")
        review = wx.StaticText(panel, label="评审")

        tcTitle = wx.TextCtrl(panel)
        tcAuthor = wx.TextCtrl(panel)
        tcReview = wx.TextCtrl(panel, style=wx.TE_MULTILINE)

        fgs.AddMany([(title), (tcTitle, 1, wx.EXPAND), 
            (author), (tcAuthor, 1, wx.EXPAND),
            (review, 1, wx.EXPAND), (tcReview, 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)

def main():
    app = wx.App()
    sample = SampleFlexGridSizer(None,"实战wxPython: FlexGridSizer演示")
    sample.Show()
    app.MainLoop()

if __name__ == "__main__":
    main()

在代码中,我们加入了以下两句:

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

它们将控制第三行和第二列根据窗口的调整其尺寸做相应调整.在上述界面中,前面两列的文本编辑框沿水平方向扩张,而第三列的文本框则同时沿水平和垂直方向进行扩展。注意,为了达到上述扩展效果,我们需要指定相应控件的为扩展的(设置相应标记为wx.EXPAND)。

上述示例的最终运行效果如图4所示:

 图4:FlexGridSizer布局演示

五、wx.GridBagSizer

在wxPython中还提供了一种更灵活的网格布局方式wx.GridBagSizer, wx.GridBagSizer显式支持在指定的网格位置添加一个控件,同时也可以指定控件跨越行或者列。因此它可以更灵活地实现更复杂的布局效果。wx.GridBagSizer的继承关系如图5所示:

 图5:wx.GridBagSizer继承关系图

wx.GridBagSizer常用方法:

  • Add(): 在网格指定位置处添加一个控件;
  • GetItemPosition(): 返回指定位置的控件项;
  • SetItemPosition(): 在网格指定位置放置一个控件项;
  • GetItemSpan(): 返回一个控件项的行/列跨越数;
  • SetItemSpan(): 设置一个控件项的行/列跨越数。

六、wx.GridBagSizer示例

下面的代码演示了如何使用wx.GridBagSizer实现一个相对复杂的布局:

# 演示wx.GridBagSizer布局

import os
import wx

class SampleGridBagSizer(wx.Frame):
    
    def __init__(self, parent, title):
        super(SampleGridBagSizer, self).__init__(parent, title=title)

        self.InitUi()
        self.Centre()

    def InitUi(self):

        panel = wx.Panel(self)

        # GridBagSizer作为panel的主布局
        sizer = wx.GridBagSizer(5, 5)

        labelJavaClass = wx.StaticText(panel, label="Java类") # Java class
        sizer.Add(labelJavaClass, pos=(0, 0), flag=wx.TOP|wx.LEFT|wx.BOTTOM, border=15)

        imgPath = os.path.dirname(__file__) #图片文件的绝对路径
        icon = wx.StaticBitmap(panel, bitmap=wx.Bitmap(imgPath + "/python-logo.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)

        labelName = wx.StaticText(panel, label="名称") # Name
        sizer.Add(labelName, pos=(2, 0), flag=wx.LEFT, border=10)

        tcName = wx.TextCtrl(panel)
        sizer.Add(tcName, pos=(2, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND)

        labelPackage = wx.StaticText(panel, label="包")    # Package
        sizer.Add(labelPackage, pos=(3, 0), flag=wx.LEFT|wx.TOP, border=10)

        tcPackage = wx.TextCtrl(panel)
        sizer.Add(tcPackage, pos=(3, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND, border=5)

        buttonBrowse1 = wx.Button(panel, label="浏览...") # Browse...
        sizer.Add(buttonBrowse1, pos=(3, 4), flag=wx.TOP|wx.RIGHT, border=5)

        labelExtends = wx.StaticText(panel, label="扩展") # Extends
        sizer.Add(labelExtends, pos=(4, 0), flag=wx.TOP|wx.LEFT, border=10)

        comboExtends = wx.ComboBox(panel)
        sizer.Add(comboExtends, pos=(4, 1), span=(1, 3), flag=wx.Top|wx.EXPAND, border=5)

        buttonBrowse2 = wx.Button(panel, label="浏览...") # Browse...
        sizer.Add(buttonBrowse2, pos=(4, 4), flag=wx.TOP|wx.RIGHT, border=5)

        sbOptAttr = wx.StaticBox(panel,  label="可选属性") # Optional Attributes

        # 垂直布局
        vboxSizer = wx.StaticBoxSizer(sbOptAttr, wx.VERTICAL)

        chkPublic = wx.CheckBox(panel, label="公共")    # Public
        vboxSizer.Add(chkPublic, flag=wx.LEFT|wx.TOP, border=5)

        chkGeneDefConstructor = wx.CheckBox(panel, label="创建缺省构造函数") # Generate Default Constructor
        vboxSizer.Add(chkGeneDefConstructor, flag=wx.LEFT, border=5)

        chkGeneMainMethod = wx.CheckBox(panel, label="创建Main方法")
        vboxSizer.Add(chkGeneMainMethod, flag=wx.LEFT|wx.BOTTOM, border=5)

        sizer.Add(vboxSizer, pos=(5, 0), span=(1,5), flag=wx.EXPAND|wx.TOP|wx.LEFT|wx.RIGHT, border=10)

        buttonHelp = wx.Button(panel, label="帮助")  # Help
        sizer.Add(buttonHelp, pos=(7, 0), flag=wx.LEFT, border=10)

        buttonOK = wx.Button(panel, label="确定")   # OK
        sizer.Add(buttonOK, pos=(7, 3))

        buttonCancel = wx.Button(panel, label="取消")
        sizer.Add(buttonCancel, pos=(7, 4), span=(1, 1), flag=wx.BOTTOM|wx.RIGHT, border=10)

        sizer.AddGrowableCol(2)

        panel.SetSizer(sizer)
        sizer.Fit(self)


def main():
    app = wx.App()
    sample = SampleGridBagSizer(None, title="实战wxPython: 网格布局演示-创建JAVA类")
    sample.Show()
    app.MainLoop()

if __name__ == '__main__':
    main()

其运行效果如图6所示:

 图6:wx.GridBagSizer布局演示

七、本文知识点

  • 网格布局的基本使用方法;
  • 了解和使用GridSizer;
  • 了解和使用FlexGridSizer;
  • 了解和使用GridBagSizer。

前一篇:实战wxPython:011 - 布局管理之网格布局

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值