posts - 257, comments - 1329, trackbacks - 52, articles - 8
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

        在上一篇Post中,我已经对前四个Demo做了简要的介绍,但那四个只是饭前的开胃小菜,好戏还在后头呢。嘿,上菜咯!
         Demo 5 使用WinFX:IronPython的开发从来都紧跟.NET Framework的升级,更重要的,它也十分重视
IronPython在未来开发平台上的应用。而这个Demo则向大家展示了它运用WinFX的能力。
         Demo 5.1 使用WinFX提供的语音功能:这个Demo很简单,无非就是使用SpeechSynthesizer而已。但
是由于这个Demo制作的时候已经比较早了,其中的一些information并不是最新的,跟着Demo来做,是无法得到正确结果的,需要对代码进行一些修改。代码解析如下:

1. from AvalonStartup import *:这个语句是将AvalonStartup module中的所有内容导入。如果依葫芦画瓢地输入该行代码,将会出现ImportError: No module named AvalonStartup这样的错误信息。实际上,这个module并非是WinFX的library,而是一个IronPython的module。Jim所用的AvalonStartup来自哪里就不得而知了,但是我们可以发现这个module导入了很多基本的WinFX library供后面的Demo使用,而在IronPython的Tutorial目录下有类似作用的IronPython文件:avalon.py。找到了替代品,总算可以松口气了。avalon.py是为后面的Demo做准备的,而要完成这个语音Demo并不需要用到它。我们可以完全忽略这行代码,然后输入如下三行代码即可:
   
import
 sys
    sys.LoadAssemblyByName(
"System.Speech"
)
   
from System.Speech.Synthesis import *

2. ss 
= SpeechSynthesizer(): 构造SpeechSynthesizer对象实例;
3. ss.SpeakTextAsync(
"Hello from IronPython"):开始还以为会跟Demo演示的一样,以单词为单位读出来,结果竟然是一个个字母念了出来!后来想了一下,也许这个语音功能可以识别当前系统的Locale,才会闹出读字母的笑话,于是尝试了一下让它念念中文:ss.SpeakTextAsync("你好")。果然,它把"你好"读出来了!虽然发音有些浑浊,但还是能够听得出说的是"你好"
,这着实让我激动了好一会。


        Demo 5.2 使用WinFX提供的类库构造UI:这部分的Demo并没有什么难度,但是确实比较有趣,因为你可以动态地改变一个Window的大小以及增加新的Control,并且为这些Control增加相应的事件处理方法。需要注意的一点是,之前提到的avalon.py在这里派上用场了。

1. from avalon import 导入IronPython Tutorial目录下的avalon module(avalon.py),这是能够完成这个Demo的必备条件。当然,如果你有足够的好奇心,也可以打开avalon.py看一下,这个文件到底包含了什么内容。注意,Demo中并没有这行代码,只有类似的from AvalonStartup import *
2. w 
=
 Window()  构建Window对象实例;
3. w.Show()  显示构建的Window实例。当这行代码执行之后,Window窗口将显示出来;
4. w.SizeToContent 
=
 SizeToContent.WidthAndHeight 设定Window的大小依据Window包含的内容来改变;
5. b 
= Button(Content="Click Me") 构造Button实例,同时设定该实例的Content属性为"Click Me"

6. w.Content 
=
 b  设定Window实例的Content属性为Button实例b,实际上就是令Window包含Button;
7. b.FontSize 
= 100
  改变Button实例b的FontSize。以上两行代码执行完毕之后,都能马上看到效果,十分快捷;
8.
def doit(*args): print args  这里有一个IronPython的特殊语法:随机参数表。*
args表示参数列表,也就实说args是一个Tuple(你可以把它看作是ReadOnly的List),它包含了传入该方法的所有实参。详细的内容可以参见我的另外一篇Post:美妙的Python又来了
9. b.Click 
+=
 doit  这就是大家都很熟悉的为Click事件增加Event Handler。在这行代码执行之后,点击Click Me的button,就会在控制台将Click事件涉及的参数:EventSender和EventArgs打印出来。


        Demo 5.3 装载XAML文件:Windows Presentation Foundation一个有趣的特性是使用了XAML——用于定义UI的XML文件。XAML的出现使得UI的设计变得更加简单且高效,也使得程序员和美工可以更好的协作,进步可谓是革命性的。代码解析如下:

1. calc = LoadXaml('calc.xaml')  装载XAML文件。LoadXaml是定义在avalon.py中的方法,而calc.xaml则存储于IronPython的Tutorial目录下;
2. w.Content 
=
 calc  将之前创建的Window实例的Content设为calc——从XAML获得的对象。执行完毕之后,一个漂亮的计算器就呈现在眼前了。注意该Demo是在Demo5.2的基础上进行的,那么w这个Window实例是处于显示状态的,如果你是单独体验这个Demo,别忘了调用w.Show()将Window显示出来;
3.
for node in
 Walk(calc): Print node  将calc对象所包含的子对象节点打印出来。Walk也是定义在avalon.py中的方法。通过一行代码的执行,你可以得到一个有关UI的对象列表;
4. [node 
for node in Walk(calc) if
 isinstance(node, Button)] 将calc对象中包含的所有Button对象罗列出来,存到一个临时的List中;
5. buttons 
=
 _  这是一个简单的赋值语句,而其中的_则是引用最近的一个临时变量。那么buttons就是一个包含calc中所有Button对象的List了;
6.
for b in buttons: print
 b 这句已经不需要多解释了;
7. 
for b in buttons: b.Background =
 Brushes.Blue 改变所有button的背景颜色;
8.
for b in buttons: b.LayoutTransform = RotateTransform(90)  改变所有button排列的角度。你会发现所有的button都卧倒了,90表示角度,而这个角度是可以随意设定的,正/负则表示按照顺/
逆时针方向旋转;
9.
def
 sayit(b, e): ss.SpeakTextAsync(b.Name) 定义Event Hanlder。同样要注意ss是来自Demo5.1的变量;
10.
for b in buttons: b.Click += sayit  为Click事件增加Event Handler。执行完这行代码之后,点击button,会听到相应的读音,可惜的是calc.xaml中把button的name都设为one、equal这样的英文名字,我们听到的又是一个个字母朗读的效果了。


        好了,Demo 5就讲解到这里,希望你会喜欢上这些来自IronPython和WinFX有趣的特性。在下一篇
Post中,我们将继续关注剩下的两个Demo。

Feedback

#1楼    回复  引用  查看    

2005-12-28 09:12 by redmoon      
我用的Dec的WinFX Runtime,但是Demo5.1和Demo5.2 都没有运行起来,你运行起来没有?

#2楼 [楼主]   回复  引用  查看    

2005-12-28 09:22 by FantasySoft      
To redmoon: 这两个Demo都是可以运行的,以上总结的也是我实际试验的结果。你遇到的错误是什么呢?

要特别注意,Demo中的AvalonStartup是找不到的,我在文中提到了解决办法。

#3楼    回复  引用  查看    

2005-12-28 14:44 by ccBoy      
不错,喜欢这样认真学习的态度。我只调了其中的一个例子

应该有一个控制 MS Agent 的Demo吧,这个是最经典的。用Python 脚本控制Merlin(Microsoft Agent character 的一种)跑来跑去,做不同的动作。(好像说这个功能不能被拷屏录下来)

比较COOL的是这次加了对Avalon 对象和动作的支持,"Rob 说第一个版本的WPF 不会考虑脚本的场景,所以IronPython 将是一个非常好的选择和配合"

http://www.dotnettools.org/Blog/article.asp?id=21

#4楼 [楼主]   回复  引用  查看    

2005-12-28 16:30 by FantasySoft      
哈哈,有朋自咫尺天涯中来,不亦说乎。 So happy to see your comment, ccBoy.

Merlin是最后一个Demo,Jim几乎是轻描淡写地带过了,您不提醒,我还差点忘了呢。晚上回去得把它补上,谢谢啦! :)

#5楼    回复  引用  查看    

2005-12-29 09:24 by redmoon      
错了,原来你说的Demo是Jim在那个WMV里面做的。
而我说的是E:\TECH\IronPython-0.9.6\Tutorial 这个目录里面的关于Avlon的Tutorial。

Tutorial 2: Advanced IronPython
Exercise 3: Windows Presentation Foundation (Avalon)
Task 1: Simple Avalon Application
错误如下:
>>> w.Text = "My Avalon Application"
Traceback (most recent call last):
at <shell>
TypeError: can't set arbitrary attributes on built-in type System.Windows.Window

而我Merlin那个也没有通过:
Tutorial 3: IronPython and COM interoperability
Exercise 1: Merlin the Wizard
Task 2: Using COM objects from IronPython
错误如下:
>>> a = AgentServerClass()
Traceback (most recent call last):
at <shell>
System.InvalidCastException: Creating an instance of the COM component with CLSI
D {D45FD2FC-5C6E-11D1-9EC1-00C04FD7081F} from the IClassFactory failed due to th
e following error: 80004002.

#6楼    回复  引用  查看    

2005-12-29 09:26 by redmoon      
Avalon的错误,我估计是WinFX的版本不一致。Merlin的错误我就想不出原因了。

#7楼    回复  引用  查看    

2005-12-29 09:33 by redmoon      
Hi Iain,

What an interesting coincidence. I just finished a sweep through the tutorial, updating it with the new Avalon samples that work with the December CTP. The WinFX has changed substantially between the September and December CTPs. You pretty much found the right solutions to all roadblocks that you encountered. As for the animation, I wasn't able to find what the new way of doing things was so it is the only thing that I didn't get working. However, the tutorial will be updated (as well as the Embed directory sample) in the next release.

Thanks!
Martin
====
就是版本的问题。

#8楼 [楼主]   回复  引用  查看    

2005-12-29 10:20 by FantasySoft      
To redmoon: 噢,原来是Tutorial的Demo。由于Tutorial是IronPython 0.9.4时候的产物了,而当时看过了C#和IronPython协作的那个Exercise之后,就没有怎么在意其他Exercise了,特别是WinFX特性运用方面。

至于Merlin那个Exercise,我昨天晚上调试到快两点,开始也是遇到了和你相同的错误,后来尝试了用IronPython 0.9.4去试,则在Load Assembly的时候就出了错。之后再用IronPython 0.9.6去尝试,也出现了和0.9.4一样的错误,哪怕我重新使用tlbimp工具生成新的Assembly,错误依旧。看来这个Assemly的问题还是挺值得研究的,今天晚上继续调试。 What interesting thing!

#9楼 [楼主]   回复  引用  查看    

2006-01-01 04:22 by FantasySoft      
To redmoon: Merlin的问题有了解决方案,我想你从Mail List中应该也看到了。无法创建COM component实例的原因是线程的问题。只需要在IronPythonConsole的PythonCommandLine类中的Main函数之前增加[STAThread]即可。

BTW: IronPython 1.0 已经发布了,新版本也解决了Merlin的问题,解决的办法跟我上面说到的是一样的。

#10楼    回复  引用    

2007-04-04 10:10 by 翻译公司 [未注册用户]
HOHO

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2005-12-28 00:50 编辑过


相关链接: