【Python】 用户图形界面GUI wxpython II

wxpython - 布局和事件

  这章主要记录布局器Sizer以及事件的用法。

// 目前还需要记录的:Sizer的Add方法加空白,Sizer的Layout,Sizer的Remove如何有效

  ■  布局

  之前介绍的所有组件,如果不把它们的pos写死的话,页面上它们会互相重叠,导致没法看。而Sizer就是一个很好的优化布局的工具,通过此可以灵活地管理组件之间的相对位置。

  Sizer大概的可以被分成GridSizer(网格布局)和BoxSizer(线性布局).Sizer的用法概括起来就是创建Sizer之后将其关联到一个对象(通常是Panel)。然后用诸如Add,Insert等方法为Sizer添加组件。调用Fit等方法可以让Sizer自动计算子部件尺寸的大小。去除一个部件和Sizer的关联可以用Sizer.Detach方法。//这个存疑,尝试了各种各样的方法,包括了窗口Refresh等等,效果都不好

  ●  GridSizer  网格布局

  构造方法中有四个参数决定了这个布局地大致样式,分别是rows,cols,vgap,hgap分别表示网格行数,列数,两相邻列间相隔像素数,两相邻行间相隔像素数。

  在用Add方法添加组件的时候默认是先填满一行再开始填下一行。简单GridSizer严格遵守网格布局的含义,当窗口大小发生变化时,其网格的大小也会相应变化,导致加在网格中的组件大小或间距也会发生相应的变化。GridSizer更加适合表格作业が,其改进版的FlexGridSizer可以更加灵活的设置大小和缩放的关系。

  网格布局举例;

testSizer = GridSizer(rows=2,cols=2)

totalPanel = Panel(self,-1)
text1 = StaticText(totalPanel,-1,"Text1:")
btn1 = Button(totalPanel,-1,"Button1")
text2 = StaticText(totalPanel,-1,"Text2:")
btn2 = Button(totalPanel,-1,"Button")

testSizer.Add(text1,flag=ALIGN_CENTER)
testSizer.Add(btn1,flag=ALIGN_CENTER)
testSizer.Add(text2,flag=ALIGN_CENTER)
testSizer.Add(btn2,flag=EXPAND)

totalPanel.SetSizer(testSizer)

  界面效果:

  

  ●  FlexGridSizer

  其构造方法和GridSizer是类似的。但它和GridSizer的区别在于,在默认情况下FGS的网格不会随着窗口的大小变化而变化。而所谓不默认的情况,就是用Sizer对象调用AddGrowableRow(x,m)/AddGrowableCol(y,n)。这两个方法的意思是使得某一行或某一列的网格会随着窗口大小而变化。比如AddGrowableRow(1)是说让第二行会随着窗口纵向长度变化而变化,可以添加第二个参数来决定这行变化的权重。比如AddGrowableRow(0,1);AddGrowableRow(1,2)的意思就是把第一行和第二行都设置为可纵向延伸,且窗口延伸一个单位,第一行延伸三分之一while第二行延伸三分之二个单位。同理AddGrowableCol就是控制列在横向方向的延伸和权重的。(权重这个概念在后面的BoxSizer中还会再提到)

  注意:这里所说的可延伸都是只网格的可延伸,而具体到这个网格里面的组件可不可延伸扩展,,就要看Sizer在Add时的flag了。比如说flag设置为ALIGN_CENTER的话,网格延伸了但是组件始终保持在网格的正中间。EXPAND的话组件始终填满整个网格等等。

  反过来说,在Sizer.Add组件时如果设置了flag=EXPAND但是这个组件所在的行列都没有被设置成Growable的话就是白瞎,窗口变动无法引起网格变动自然也无法引起组件的变动了。

  

  ●  GridBagSizer

  GS和FGS在添加时都是默认先填满第一行,填满第一行之后再转到第二行。而GBS可以指定在哪行哪列的网格添加组件。

  GBS的构造方法没有rows和cols参数,最终Sizer会以几行几列的方式呈现取决于添加的靠近右下角的那个组件有多右下角= =

  GBS在Add的时候必须指出两个参数,pos=(x,y)以及size=(m,n)意思是组件填充在第x+1行和第y+1列的网格以及该组件将占据m行n列的位置(有点像xlrd,xlwt里面的合并单元格属性)

  ●  BoxSizer

  BS是一个水平行or垂直列,具体是哪个通过构造方法的参数是wx.HORIZONTAL还是wx.VERTICAL来决定。对于HORIZONTAL,其可延伸方向就是纵向,对于VERTICAL自然就是横向了。

  BS的Add方法中有proportion参数。proportion参数类似于上面提到的AddGrowableRow的第二个参数类似,就是表明了窗口在可延伸方向上占的延伸权重。通常可以把组件添加到几个HORIZONTAL的sizer里,再把这些sizer作为组件添加到一个VERTICAL的sizer里面去,形成一个看起来比较舒服的页面。注意,如果需要有窗口延伸时组件也延伸的效果的话就需要让那几个HORIZONTAL的sizer也要有flag=EXPAND,因为sizer和panel一样也是有大小的,如果不设置EXPAND,这些sizer的大小也是不会变的。

  关于BS的Add,还有一点常用的,就是flag=LEFT|RIGHT|TOP|BOTTOM|ALL,border=xx 通过flag=选项中的一个或几个,并且配合border的数值,调整被Add的元素始终保持指定的几条边和周围的相距border数值个像素的位置。因为是常用的就不啰嗦了。

  ■  事件

  人和组件元素的一些互动会触发事件,事件在wx中以以下方式表示:

    wx.EVT_BUTTON  按下按钮的事件

  常用的事件还有:

    EVT_SIZE  由于用户干预或由程序实现,当一个窗口大小发生改变时发送给窗口。
    EVT_MOVE  由于用户干预或由程序实现,当一个窗口被移动时发送给窗口。

    EVT_CLOSE   当一个框架被要求关闭时发送给框架。除非关闭是强制性的,否则可以调用event.Veto(true)来取消关闭。

    EVT_PAINT   无论何时当窗口的一部分需要重绘时发送给窗口。

    EVT_CHAR   当窗口拥有输入焦点时,每产生非修改性(Shift键等等)按键时发送。

    EVT_IDLE   这个事件会当系统没有处理其它事件时定期的发送。

    EVT_LEFT_DOWN   鼠标左键按下。

    EVT_LEFT_UP   鼠标左键抬起。

    EVT_LEFT_DCLICK   鼠标左键双击。

    EVT_MOTION   鼠标在移动。

    EVT_SCROLL   滚动条被操作。这个事件其实是一组事件的集合,如果需要可以被单独捕捉。

    EVT_MENU   菜单被选中。

  此外还可以自定义事件,不过我觉得暂时还用不到就不啰嗦细写了。可以参考http://blog.csdn.net/tingsking18/article/details/4033639

  ●  Bind方法

  仅仅有事件还是不够的,必须要把引起事件的组件和事件处理结合起来,这里用到的就是Bind函数

  Bind隶属于wx.EvtHandler,是所有可显示对象(包括Frame在内的绝大多数组件)的父类,所以 这些组件都可以调用Bind。允许一个组件Bind多个事件,此时事件的处理函数中可以写event.Skip(True)来标识某个事件处理函数对改事件不做处理而直接跳过。

  Bind的定义是Bind(绑定事件类型,事件处理器,事件源对象),但是通常可以通过某个组件来调用Bind比如btn.Bind(绑定事件类型,事件处理器)就好了。事件类型就是上面那一大票,而事件处理器传递的是个函数对象。这个函数对象要求有且只有一个没有默认值的参数,event。这样的话就引起了一个问题,当我想要传递一些额外的参数给事件处理函数时该怎么办?比如:

#这样子是运行正常的
btn.Bind(EVT_BUTTON,test)
def test(event):
    print "Hello"

#但这样会报参数个数不对的错
btn.Bind(EVT_BUTON,test)
def test(event,name):
    print "Hello,%s"%(name)

#而在Bind的时候又不能直接给test加参数。。

  这种情况其实可以归类为一个更普遍一点的问题,就是如何为一个(在定义时没有给出参数默认值的)函数对象参数默认值?

  解决方法:用lambda:

btn.Bind(EVT_BUTTON,lambda evt,name="Frank":test(evt,name))
def test(event,name):
    print "Hello,%s"%(name)

  通过lambda为函数本身再做一层包装而返回一个包装后的函数对象(感觉有点像装饰器的意思)

■  在整个wx中加入事件之后可以看到,组件之间的关系复杂起来了。建议的程序构造方式是这样子的:

  每一个窗口都是一个类,不同窗口用不同类来表示

  窗口中的组件写在类的构造方法里,并且把需要进行取值等和其他方法互动操作的组件要设置成“self.组件”。与组件绑定的事件处理方法写成“self.方法”的类方法。需要子窗口时把子窗口的构造方法中加个parent参数,然后在构造子窗口时把父窗口传递进去即可。

时间: 2024-10-09 23:06:57

【Python】 用户图形界面GUI wxpython II的相关文章

【Python】 用户图形界面GUI wxpython III

wxpython - 更多组件 我写到的这些组件可能一来不是很详细,二来不是最全的,想要更好地用这些组件,应该还是去看看教程和别的示例.比较简单的,推荐http://download.csdn.net/album/detail/459 辛星wpython教程 ■ 复选框 CheckBox 复选框需要对每个单独的选项构建,常用的构造方法是:CheckBox(parent,id,label,pos,size) 事件中的EVT_CHECKBOX是指被Bind的checkbox被勾选或取消时发生的事件

非专业码农 JAVA学习笔记 用户图形界面设计与实现-所有控件的监听事件

用户图形界面设计与实现-监听事件 System.applet.Applet (一)用户自定义成分 1.绘制图形 Public voit piant(Ghraphics g){  g.drawLine等图形名称(坐标1234);g.file图形名(坐标123)} 2.设置字体-Font类 (1)定义font:Font myfont=new Font(“字体”,”样式”,字号); 例如:Font myfont=new Font(“宋体”,Font.BOLD,12); (2)引用定义的Font:类/容

PyGObject笔记1——用Python写图形界面

PyGObject is a Python extension module that gives clean and consistent access to the entire GNOME software platform through the use of GObject Introspection. PyGObject provides full support of GObject Introspection and all of its features (callbacks,

python写图形界面

作为Pyhon开发者,你迟早都会碰到图形用户界面(GUI)应用开发任务,这时候我们就需要一些界面库来帮助我们快速搭建界面,python的界面库很多,我认识的并不多,这里只列出几种我认识的 1.tkinter Tkinter(也叫Tk接口)是Tk图形用户界面工具包标准的Python接口.Tk是一个轻量级的跨平台图形用户界面(GUI)开发工具.Tk和Tkinter可以运行在大多数的Unix平台.Windows.和Macintosh系统. Tkinter 由一定数量的模块组成.Tkinter位于一个名

十. 图形界面(GUI)设计2.框架窗口

窗口是GUI编程的基础,小应用程序或图形界面的应用程序的可视组件都放在窗口中,在GUI中,窗口是用户屏幕的一部分,起着在屏幕中一个小屏幕的作用.有以下三种窗口: Applet窗口:Applet类管理这个窗口,当应用程序程序启动时,由系统创建和处理: 框架窗口(JFrame):这是通常意义上的窗口,它支持窗口周边的框架.标题栏,以及最小化.最大化和关闭按钮: 一种无边框窗口(JWindow):没有标题栏,没有框架,只是一个空的矩形. 用Swing中的JFrame类或它的子类创建的对象就是JFram

十. 图形界面(GUI)设计1.图形界面设计基础

早先程序使用最简单的输入输出方式,用户在键盘输入数据,程序将信息输出在屏幕上.现代程序要求使用图形用户界面(Graphical User Interface,GUI),界面中有菜单.按钮等,用户通过鼠标选择菜单中的选项和点击按钮,命令程序功能模块.本章学习如何用Java语言编写GUI科学试验,如何通过GUI实现输入和输出. AWT和Swing 先前用Java编写GUI程序,是使用抽象窗口工具包AWT(Abstract Window Toolkit).现在多用Swing.Swing可以看作是AWT

十. 图形界面(GUI)设计3.标签、按钮和按钮事件

标签和按钮也许是图形界面中最常见的两种组件,按钮又总是与激发动作事件有关. 标签 标签(JLabel)是最简单的Swing组件.标签对象的作用是对位于其后的界面组件作说明.可以设置标签的属性,即前景色,背景色.字体等,但不能动态地编辑标签中的文本. 程序关于标签的基本内容有以下几个方面: 声明一个标签名: 创建一个标签对象: 将标签对象加入到某个容器. JLabel类的主要构造方法是: JLabel ():构造一个无显示文字的标签: JLabel (String s):构造一个显示文字为s的标签

GUI用户图形界面

/*记事本小练习 * GUI & IO综合运用 */ import java.awt.*; import java.awt.event.*; import java.io.*; public class Test33 { public static void main(String[] args) { MyTest mytest = new MyTest(); mytest.frameInit(); //运行窗口 } } class MyTest{ //定义成员变量,包括窗体,文本区域,对话框,

python之图形界面

12.1 丰富的平台 在编写python GUI程序前,需要决定使用哪个GUI平台.wxpython----跨平台pythonGUI工具包 确保所选择的二进制版本要对应python的版本,例如,针对python2.3进行编译的wxpython并不能用于python2.4. 12.3.1 开始 开始需要wx模块: import wx 编写wxPython程序的方法很多,但不可避免的事情是创建应用程序对象.基本的应用程序类叫做ex.App,它负责幕后所有的初始化.最简单的wxPython程序应该像下