4.4 如何将PyCrust应用于wxPython应用程序。
让我们假设你已经用wxPython创建了一个程序,并且你的程序正在工作,现在你想更好地了解它是如何工作的。在这章的前面你已经看到了PyCrust的特性,它们看起来对于理解你的程序的功能是非常有用的。
通过将你的程序的名字传递给PyWrap,你能够用PyCrust shell来启动你的程序,不需要对你的程序作任何的改变。下例4.2显示了一个名为spare.py的程序,我们准备对它使用PyCrust。
例4.2
#!/usr/bin/env python
"""Spare.py is a starting point for simple wxPython programs."""
import wx
class Frame(wx.Frame):
pass
class App(wx.App):
def OnInit(self):
self.frame = Frame(parent=None, id=-1, title='Spare')
self.frame.Show()
self.SetTopWindow(self.frame)
return True
if __name__ == '__main__':
app = App()
app.MainLoop()
为了运行这个程序时使用PyCrust,要将该程序的全路径传递给PyWrap。在Linux上,命令行类似如下:
$ pywrap spare.py
在windows下,命令行类似如下:
F:/>python pywrap.py spare.py
在 开始的时候,PyWrap试图导入命令行所包括的模块。然后PyWrap在模块中寻找wx.App的子类,并创建子类的一个实例。之后,PyWrap创建 一个带有shell的wx.py.crust.CrustFrame窗口,把这个应用程序对象显示在PyCrust的名字空间树中,并且启动 wxPython事件循环。
PyWrap的源码显示在例子4.3中。它显示了如何用少量的代码将大量的功能增加到你的程序中。
例4.3
"""PyWrap is a command line utility that runs a python
program with additional runtime tools, such as PyCrust."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id: PyCrust.txt,v 1.15 2005/03/29 23:39:27 robind Exp $"
__revision__ = "$Revision: 1.15 $"[11:-2]
import os
import sys
import wx
from wx.py.crust import CrustFrame
def wrap(app):
wx.InitAllImageHandlers()
frame = CrustFrame()
frame.SetSize((750, 525))
frame.Show(True)
frame.shell.interp.locals['app'] = app
app.MainLoop()
def main(modulename=None):
sys.path.insert(0, os.curdir)
if not modulename:
if len(sys.argv) < 2:
print "Please specify a module name."
raise SystemExit
modulename = sys.argv[1]
if modulename.endswith('.py'):
modulename = modulename[:-3]
module = __import__(modulename)
# Find the App class.
App = None
d = module.__dict__
for item in d.keys():
try:
if issubclass(d[item], wx.App):
App = d[item]
except (NameError, TypeError):
pass
if App is None:
print "No App class was found."
raise SystemExit
app = App()
wrap(app)
if __name__ == '__main__':
main()
运行了PyWrap命令之后,来自spare的简单的框架(frame)和PyCrust的框架都显示出来。
PyCrust in action
现在让我们看看,在PyCrust shell中我们对spare.py应用程序框架做些什么。图4.10显示了这个结果。我们将通过导入wx和增加一个画板到我们的框架作为开始:
>>> import wx
>>> app.frame.panel = wx.Panel(parent=app.frame)
>>> app.frame.panel.SetBackgroundColour('White')
True
>>>
图4.10
增加到框架的画板开始时是默认的银灰色,然后它被改变到白色。然而,设置画板背景色不立即改变它的显示。这需要去触发一个事件来导致画板重绘,以使用它的新颜色属性。一个触发这样事件的方法是要求画板刷新自身:
>>> app.frame.panel.Refresh()
现在一个白色的画板显示了,我们对于理解wxPython如何工作的细节又进了一步。
接下来,让我们增加一个状态栏:
>>> app.frame.statusbar = app.frame.CreateStatusBar(number=3)
>>> app.frame.statusbar.SetStatusText("Left", 0)
>>> app.frame.statusbar.SetStatusText("Center", 1)
>>> app.frame.statusbar.SetStatusText("Right", 2)
注意在不改变这个框架的尺寸情况下,这个状态栏在这个框架中是如何显示的。也要注意添加到三个状态栏中的文本的立即显示了出来,而不要求刷新。现在让我们增加一个菜单和一个菜单栏:
>>> app.frame.menubar = wx.MenuBar()
>>> menu = wx.Menu()
>>> app.frame.menubar.Append(menu, "Primary")
True
>>> app.frame.SetMenuBar(app.frame.menubar)
>>> menu.Append(wx.NewId(), "One", "First menu item")
<wx.core.MenuItem; proxy of C++ wxMenuItem instance at
_d8043d08_p_wxMenuItem>
>>> menu.Append(wx.NewId(), "Two", "Second menu item")
<wx.core.MenuItem; proxy of C++ wxMenuItem instance at
_40a83e08_p_wxMenuItem>
>>>
当 你在PyCrust shell中处理你自己的wxPython对象时,注意改变对你正在运行的程序的影响。试试回答后面的问题。在框架中菜单何时才实际 显示出来的?在程序运行的时候,你能改变菜单的哪些属性?你能够让它们无效吗?交互地探究这些可以帮助你更好的理解wxPython,同时当你写真实的代 码时给你带来更大的自信。
到目前,我们已经花了很多节讨论PyCrust,我们下面准备看一看Py包的其余的东西。
让我们假设你已经用wxPython创建了一个程序,并且你的程序正在工作,现在你想更好地了解它是如何工作的。在这章的前面你已经看到了PyCrust的特性,它们看起来对于理解你的程序的功能是非常有用的。
通过将你的程序的名字传递给PyWrap,你能够用PyCrust shell来启动你的程序,不需要对你的程序作任何的改变。下例4.2显示了一个名为spare.py的程序,我们准备对它使用PyCrust。
例4.2
#!/usr/bin/env python
"""Spare.py is a starting point for simple wxPython programs."""
import wx
class Frame(wx.Frame):
pass
class App(wx.App):
def OnInit(self):
self.frame = Frame(parent=None, id=-1, title='Spare')
self.frame.Show()
self.SetTopWindow(self.frame)
return True
if __name__ == '__main__':
app = App()
app.MainLoop()
为了运行这个程序时使用PyCrust,要将该程序的全路径传递给PyWrap。在Linux上,命令行类似如下:
$ pywrap spare.py
在windows下,命令行类似如下:
F:/>python pywrap.py spare.py
在 开始的时候,PyWrap试图导入命令行所包括的模块。然后PyWrap在模块中寻找wx.App的子类,并创建子类的一个实例。之后,PyWrap创建 一个带有shell的wx.py.crust.CrustFrame窗口,把这个应用程序对象显示在PyCrust的名字空间树中,并且启动 wxPython事件循环。
PyWrap的源码显示在例子4.3中。它显示了如何用少量的代码将大量的功能增加到你的程序中。
例4.3
"""PyWrap is a command line utility that runs a python
program with additional runtime tools, such as PyCrust."""
__author__ = "Patrick K. O'Brien <pobrien@orbtech.com>"
__cvsid__ = "$Id: PyCrust.txt,v 1.15 2005/03/29 23:39:27 robind Exp $"
__revision__ = "$Revision: 1.15 $"[11:-2]
import os
import sys
import wx
from wx.py.crust import CrustFrame
def wrap(app):
wx.InitAllImageHandlers()
frame = CrustFrame()
frame.SetSize((750, 525))
frame.Show(True)
frame.shell.interp.locals['app'] = app
app.MainLoop()
def main(modulename=None):
sys.path.insert(0, os.curdir)
if not modulename:
if len(sys.argv) < 2:
print "Please specify a module name."
raise SystemExit
modulename = sys.argv[1]
if modulename.endswith('.py'):
modulename = modulename[:-3]
module = __import__(modulename)
# Find the App class.
App = None
d = module.__dict__
for item in d.keys():
try:
if issubclass(d[item], wx.App):
App = d[item]
except (NameError, TypeError):
pass
if App is None:
print "No App class was found."
raise SystemExit
app = App()
wrap(app)
if __name__ == '__main__':
main()
运行了PyWrap命令之后,来自spare的简单的框架(frame)和PyCrust的框架都显示出来。
PyCrust in action
现在让我们看看,在PyCrust shell中我们对spare.py应用程序框架做些什么。图4.10显示了这个结果。我们将通过导入wx和增加一个画板到我们的框架作为开始:
>>> import wx
>>> app.frame.panel = wx.Panel(parent=app.frame)
>>> app.frame.panel.SetBackgroundColour('White')
True
>>>
图4.10
![](https://i-blog.csdnimg.cn/blog_migrate/5a9752e91dcf448b8c72dc9e5ccb7d23.png)
增加到框架的画板开始时是默认的银灰色,然后它被改变到白色。然而,设置画板背景色不立即改变它的显示。这需要去触发一个事件来导致画板重绘,以使用它的新颜色属性。一个触发这样事件的方法是要求画板刷新自身:
>>> app.frame.panel.Refresh()
现在一个白色的画板显示了,我们对于理解wxPython如何工作的细节又进了一步。
接下来,让我们增加一个状态栏:
>>> app.frame.statusbar = app.frame.CreateStatusBar(number=3)
>>> app.frame.statusbar.SetStatusText("Left", 0)
>>> app.frame.statusbar.SetStatusText("Center", 1)
>>> app.frame.statusbar.SetStatusText("Right", 2)
注意在不改变这个框架的尺寸情况下,这个状态栏在这个框架中是如何显示的。也要注意添加到三个状态栏中的文本的立即显示了出来,而不要求刷新。现在让我们增加一个菜单和一个菜单栏:
>>> app.frame.menubar = wx.MenuBar()
>>> menu = wx.Menu()
>>> app.frame.menubar.Append(menu, "Primary")
True
>>> app.frame.SetMenuBar(app.frame.menubar)
>>> menu.Append(wx.NewId(), "One", "First menu item")
<wx.core.MenuItem; proxy of C++ wxMenuItem instance at
_d8043d08_p_wxMenuItem>
>>> menu.Append(wx.NewId(), "Two", "Second menu item")
<wx.core.MenuItem; proxy of C++ wxMenuItem instance at
_40a83e08_p_wxMenuItem>
>>>
当 你在PyCrust shell中处理你自己的wxPython对象时,注意改变对你正在运行的程序的影响。试试回答后面的问题。在框架中菜单何时才实际 显示出来的?在程序运行的时候,你能改变菜单的哪些属性?你能够让它们无效吗?交互地探究这些可以帮助你更好的理解wxPython,同时当你写真实的代 码时给你带来更大的自信。
到目前,我们已经花了很多节讨论PyCrust,我们下面准备看一看Py包的其余的东西。