为什么80%的码农都做不了架构师?>>>   

一、概念

XRC(XML Resource)的设计来源于wxWidgets,它的想法很简单,就是将界面设计的工作从程序中独立出来。具体的做法是,创建单独的XML文件,负责界面设计,程序运行的时候载入,生成界面。这样做的好处是显而易见的。首先,将繁琐的外观设计代码从程序中去掉,程序更清晰易读。其次,XRC文件独立于程序,程序运行时才调用,因此可以随意更换外观。这种思想并不是wxWidgets的原创,MFC中的RC已经有了,类似的还有HTML和CSS的关系。wxPython从wxWidgets继承而来,当然也保留了XRC。

这里有几点要补充的。一是wxPython的XRC文件中用到的类名称仍然是wxWidgets中的类名称,换句话说,wxPython和wxWidgets可以共用XRC文件,第二点要补充的是XRC文件可以编译成二进制文件XRS,或者编译成C++代码。

二、例子

先来看一个例子。

import wx

class MyFrame(wx.Frame):

def __init__(self):

wx.Frame.__init__(self, parent=None, id=wx.ID_ANY, title='My Frame')

panel = wx.Panel(self)

label1 = wx.StaticText(panel, wx.ID_ANY, 'First name:')

label2 = wx.StaticText(panel, wx.ID_ANY, 'Last name:')

self.text1 = wx.TextCtrl(panel, wx.ID_ANY)

self.text2 = wx.TextCtrl(panel, wx.ID_ANY)

button = wx.Button(panel, wx.ID_ANY, 'Submit')

sizer = wx.FlexGridSizer(rows=2, cols=2, vgap=5, hgap=5)

self.Bind(wx.EVT_BUTTON, self.OnSubmit, button)

sizer.Add(label1)

sizer.Add(self.text1)

sizer.Add(label2)

sizer.Add(self.text2)

sizer.Add((0,0)) #filler for the grid cell

sizer.Add(button)

panel.SetSizer(sizer)

sizer.Fit(self)

def OnSubmit(self, evt):

wx.MessageBox('Your name is %s %s!' %

(self.text1.GetValue(), self.text2.GetValue()), 'Feedback')

class MyApp(wx.App):

def OnInit(self):

frame = MyFrame()

self.SetTopWindow(frame)

frame.Show()

return True

if __name__ == '__main__':

app = MyApp(False)

app.MainLoop()

这是一个简单的wxPython程序。可以看到上面的代码中,除了Bind和OnSubmit,其他的代码都是和界面设计有关的,这些代码或者类似的代码出现于几乎所有的GUI程序中。下面是用XRC重新实现的代码。

import wx

from wx import xrc

class MyApp(wx.App):

def OnInit(self):

self.res = xrc.XmlResource('gui.xrc')

self.init_frame()

return True

def init_frame(self):

self.frame = self.res.LoadFrame(None, 'mainFrame')

self.panel = xrc.XRCCTRL(self.frame, 'panel')

self.text1 = xrc.XRCCTRL(self.panel, 'text1')

self.text2 = xrc.XRCCTRL(self.panel, 'text2')

self.frame.Bind(wx.EVT_BUTTON, self.OnSubmit, id=xrc.XRCID('button'))

self.frame.Show()

def OnSubmit(self, evt):

wx.MessageBox('Your name is %s %s!' %

(self.text1.GetValue(), self.text2.GetValue()), 'Feedback')

if __name__ == '__main__':

app = MyApp(False)

app.MainLoop()

看起来是不是比上面的清晰多了,当然,程序要跑起来,还需要下面的部分。下面的代码属于XRC文件。

下面的代码属于XRC文件。

<?xml version="1.0" encoding="utf-8"?>

<resource>

<object name="mainFrame">

<title>My Frame</title>

<object name="panel">

<object

<cols>2</cols>

<rows>3</rows>

<vgap>5</vgap>

<hgap>5</hgap>

<object

<object name="label1">

<label>First name:</label>

</object>

</object>

<object

<object name="text1"/>

</object>

<object

<object name="label2">

<label>Last name:</label>

</object>

</object>

<object

<object name="text2"/>

</object>

<object

<size>0,0</size>

</object>

<object

<object name="button">

<label>Submit</label>

</object>

</object>

</object>

</object>

</object>

</resource>

这段代码看起来很复杂,但是如果熟悉XML的话,应该很容易看明白它的结构。最关键的是,我们不用亲手写这些代码,很多工具,像XRCed,wxGlade都可以自动生成这些代码,你所要做的只是点几下鼠标。

三、创建XRC文件

虽然我们不用亲自写XRC文件,弄清楚它的原理还是必要的。在wxPython中,Button的构造函数是这样的。

wx.Button( parent, id, label='', pos=wx.DefaultPosition, size=wx.DefaultSize,

size=wx.DefaultSize, style=0, validator=wx.DefaultValidator, name='button')

实际使用的时候,通常没有这么多参数,

button = wx.Button(panel, wx.ID_ANY, 'Submit')

但是在XRC文件中,要创建一个Button,通常用下面的方式,

<object name="button">

<label>Submit</label>

</object>

从上面这几行代码中,我们可以得到如下信息:

1. XRC用<object> </object>表示要创建的对象。

2. XRC用所用的是C++的类名wxButton,而不是wxPython的类名wx.Button。

3. XRC用name表示对象的名称,对应于python代码中的id。

4. XRC用层次关系表示对象之间的父子关系。

下面这段代码显示了XRC文件的层次关系。

<?xml version="1.0" encoding="utf-8"?>

<resource>

<object name="mainFrame">

<title>Test Frame</title>

<object name="panel">

<object name="button">

<label>Submit</label>

</object>

</object>

</object>

</resource>

注意,所有的结构都包含在<resource> </resource>中,表示这个文件是XML Resource文件。

到目前为止,我们对XRC文件的结构已经有了初步的认识,接下来要了解的是在Python程序中如何用到它们。

四、使用XRC文件

如何使用XRC文件是wxPython+XRC框架的关键一步。在前面的代码中,我们注意到这样两行,

import wx

from wx import xrc

这里要强调的是xrc模块必须单独被导入,所以,第二行是必须的。

class MyApp(wx.App):

def OnInit(self):

self.res = xrc.XmlResource('gui.xrc')

self.init_frame()

return True

在上面这几行代码中,在上面的代码中,Self.res存储xrc文件的内容。xrc.XmlResource是导入XRC文件,创建xrc对象的关键。

self.init_frame()是用户自己定义的函数。你不一定要定义self.init_frame()函数,这样做的好处只是把初始化框架的工作单独放在一起,看起来清晰。你也可以在OnInit函数中完成所有Frame的初始化工作。下面我们来看init_frame()函数中做了什么,

self.frame = self.res.LoadFrame(None, 'mainFrame')

LoadFrame()函数返回mainFrame的引用,将顶层Frame对象载入到python程序中,第一个参数是parent,第二个参数是ID,即XRC文件中为Frame取的名字。这个函数还初始化所有的children Frame,这些工作并没有显示的表现出来,由XRC自动完成。

当你想从XRC文件中提取信息时,有两种方式可以选择,一种是XRCID(XRC_name),这个函数可以获得对象的ID;另一种是XRCCTRL(XRC_name),可以获得对象的引用。

self.panel = xrc.XRCCTRL(self.frame, 'panel')

self.text1 = xrc.XRCCTRL(self.panel, 'text1')

self.text2 = xrc.XRCCTRL(self.panel, 'text2')

对XRCCTRL需要多说两句,XRCCTRL函数返回对象的引用。但是并没有create新对象,仅仅是获取他们的引用,创建对象的工作已经在上面的LoadFrame()过程中完成了。另一个需要强调的是,调用XRCCTRL时,不一定提供直接的parent,可以使用更上一层的parent,XRCCTRL会用FindWindowById递归的往下找。也就是说,如果你迷路了,报上爷爷的名字,警察叔叔也能把你送到家。

到目前为止,构造界面的工作算是完成了。如果你熟悉GUI编程的话,马上会想到,接下来的工作应该是将Gui对象,事件和事件处理函数联系起来。这就是接下来要讲的事件绑定。

五、事件绑定

先看一段代码,

self.frame.Bind( wx.EVT_BUTTON, self.OnSubmit, id=xrc.XRCID('button') )

这是一个简单的绑定的例子,将按钮事件,事件函数和按钮ID绑定起来。前两个参数不用多解释,注意第三个参数中的XRCID函数,这个函数通过对象的名称ID返回对象的数字ID。这个数字ID是你在创建对象的时候wxPython用wx.NewID()生成的。

讲到这里有必要了解一下Bind()函数,下面是Bind()函数的定义,

Bind(event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)

最后一个参数我们忽略不计。第四个参数就是我们刚才的例子中的第三个参数,你也许会奇怪,为什么跳过了默认的第三个参数直接读取第四个参数,程序还能正常?在这种情形下,它的确就是正常。看了Bind()函数的定义之后,你也许还能想出另一种调用方法,像下面这样,

self.button = xrc.XRCCTRL(self.panel, 'button')

self.frame.Bind(wx.EVT_BUTTON, self.OnSubmit, self.button)

这当然也是正确的。但我们通常都用前一种方法。为什么呢?后一种不是更直观吗?真正的原因是,XRCCTRL只能返回wxWindow的继承类的引用,也就是有GetID方法的类。但很多情况下,我们要绑定的对象并不是wxWindow的继承类,像我们经常用到的Bind是将event handler和menu绑定起来,wxMenuItem类不是由wxWindow继承而来,因此,用XRCCTRL得不到它的引用,这种情况下,必须用XRCID来获得对象的ID,并将ID传给Bind作为参数。所以,为了简单,为了统一,我们就选择ID来作为Bind的参数。

关于利用wxPython+XRC的框架进行GUI编程,到这里就讲完了,这些东西是我从网上收集来的,半翻译半笔记最后写成现在这样。主要参考了下面这篇文章

http://wiki.wxpython.org/XRCTutorial

希望能对也为这个内容困惑的朋友有帮助。

转载于:https://my.oschina.net/kjpioo/blog/161028

GUI programming with wxPython 之 XRC相关推荐

  1. C++ GUI Programming with Qt4 Second Edition 之 前言

    前言 提前声明,本前言非原书前言翻译,仅为个人感想,并对各位大众做一简单交代. 首先,本人翻译只是个人系统学习Qt的一种方式,无论是CSDN博客发布,还是微信公众号发布,既是为了让大家更快速的上手Qt ...

  2. wxPython中XRC文件i18n示例

    wxPython中XRC文件i18n示例 (转载请注明来源于金庆的专栏) 简介 XRC文件是XML格式的界面定义文件, 用于在wxWidgets/wxPython中生成界面. i18n(Interna ...

  3. wxPython中XRC文件对 i18N的支持

    有关XRC I18N的第一个中文文档. 转自 [python-chinese] [python-chinese] 用XRC生成wxPython的界面,如何实现I18N呢? Hong Yuan hong ...

  4. GTK+ and Glade3 GUI Programming Tutorial--中文系列

    原文链接: Micah Carrick www.micahcarrick.com/12-24-2007/gtk -glade-tutorial -part -1.html Part 1 Quick O ...

  5. Python GUI制作实例 wxPython使用多线程 防假死含wxFormBuilder的文件及源码

    wxFormBuilder使用的教程较少,网上的文件源码也少. 最近使用 python 写了一个GUI,可以打开设置文件,并对xlsx文件进行处理,可以将部分信息输出到gui界面,像print输出到c ...

  6. qt5python gui cookbook_Python GUI Programming Cookbook学习笔记

    学习笔记 Chapter2 Layout Management 第一节:Arranging several labels within a label frame widget 把代码加进上一篇文章中 ...

  7. PyQt5 GUI Programming With Python 3.6 (一)

    PyQt5 PyQt5是一个基于强大的图形程式框架Qt5的python接口, 主要包含以下几个大类: ● QtCore ● QtGui ● QtWidgets ● QtMultimedia ● QtB ...

  8. C++ GUI Programming with Qt 3安装说明

    强烈建议大家在Linux下使用Qt. 虽然Qt同时支持Windows/X11/Mac OS X,但这些操作系统中只有Linux是GPL的.让人的感觉更加纯粹.而且近3-5年的Linux发行版中都会有Q ...

  9. Python GUI Programming (Tkinter)

    Tkinter编程实例 #!/usr/bin/python #coding:utf-8from Tkinter import * import sysreload(sys) sys.setdefaul ...

最新文章

  1. 重拾简单的linux指令之info 【转】
  2. MyBatis-动态SQL
  3. shell自动安装mysql_RPM包安装mysql,采用shell脚本实现自动安装、配置与卸载
  4. java 跟踪错误程序_Java异常处理 如何跟踪异常的传播路径
  5. MIP、PWA、WebGL、HTTPS,来看Web生态的领先技术
  6. web开发课程,CSS标准文档流与脱离文档流,已整理成文档
  7. MongoDB数据库查询性能提高40倍
  8. Python操作Excel删除一个Sheet
  9. python解释器的工作原理_Python GIL全局解释器锁详解(深度剖析)
  10. oracle常用网址
  11. oracle数据库的重复数据处理
  12. Karma 5:集成 Karma 和 Angular2
  13. RGB颜色 取色器/拾色器 颜色混搭
  14. 怎样控制小程序tabbar图标大小_微信小程序tabBar的基本设置-微信小程序tabbar字体大小-微信小程序tabbar高度...
  15. 新手平面设计师如何在网上接单赚钱?
  16. Java中的private关键字
  17. 如何理解反步法设计控制器?
  18. SpringSecurity之授权
  19. 用Python给娃送上一份猪年春节礼物。文末源码!
  20. 汇编语言答案(王爽)第三版

热门文章

  1. 【新版】系统架构设计师 - 软件可靠性分析与设计
  2. “应用程序配置不正确,程序无法启动”详细举例(vc2008 sp1)
  3. 【单片机系列】基于51单片机的16路抢答器
  4. 用代码制作小游戏:简单制作给孩子幸福童年
  5. 强平日志模块-埋点方案
  6. Linux磁盘管理,了解磁盘管理的魅力
  7. 2023集美大学计算机考研信息汇总
  8. Python_PyQuery使用
  9. 分享简单易用的配网终端加密模块
  10. Python爬虫下载王者荣耀全皮肤