Pygame学习笔记8:视频

视频

要在游戏中播放片头动画、过场动画等视频画面,可以使用pygame.movie模块。

要播放视频中的音乐,pygame.movie模块需要对音频接口的完全控制,不能初始化mixer模块。因此要这样完成初始化

pygame.init()
pygame.mixer.quit()

或者只初始化

pygame.display.init()

用movie = pygame.movie.Movie(’filename’)指定文件名载入视频。视频的格式可以为mpeg1。视频文件不会马上全部载入内存,而是在播放的时候一点一点的载入内存。

用movie.set_display(pygame.display.set_mode((640,480)))指定播放的surface。

用movie.set_volume(value)指定播放的音量。音量的值value的取值范围为0.0到1.0。

用movie.play()播放视频。这个函数会立即返回,视频在后台播放。这个函数可以带一个参数loops,指定重复次数。

正在播放的视频可以用movie.stop()停止播放。还可以用movie.pause()暂停播放。可以使用movie.skip(seconds)使视频前进seconds秒钟。

如有不懂的可以参考Pygame的官方例子,在Python安装目录下的\lib\site-packages\pygame\examples\movieplayer.py文件。

不过偶用官方的这个例子在Linux下播放mpeg1文件一切正常,但是在Windows下却只有声音没有画面,偶也不知道是何故。

Pygame学习笔记7:音频

音乐

要在游戏中播放背景音乐,可以使用pygame.mixer.music模块。

使用pygame.init()进行全部模块的初始化,或者只初始化音频部分:pygame.mixer.init()

使用文件名作为参数载入音乐

pygame.mixer.music.load(‘music.ogg’)

音乐可以是ogg、mp3等格式。载入的音乐不会全部放到内容中,而是以流的形式播放的,即在播放的时候才会一点点从文件中读取。

使用pygame.mixer.music.play()播放载入的音乐。该函数立即返回,音乐播放在后台进行。play方法还可以使用两个参数

pygame.mixer.music.play(loops=0, start=0.0)

loops和start分别代表重复的次数和开始播放的位置。

播放到一半可以使用pygame.mixer.music.stop()停止播放,还可以用pygame.mixer.music.pause()暂停播放。暂停播放的音乐可以用pygame.mixer.music.unpause()

来继续播放。使用pygame.mixer.music.fadeout(time)来进行淡出,在time毫秒的时间内音量由初始值渐变为0,最后停止播放。

可以用pygame.mixer.music.set_volume(value)来设置播放的音量,音量value的范围为0.0到1.0。

要判断是否在播放音乐,可以使用pygame.mixer.music.get_busy(),返回1为正在播放。在音乐播放完成时,可以用事件的方式通知用户程序。使用pygame.mixer.music.set_endevent(pygame.USEREVENT + 1),来设置当音乐播放完成时发送pygame.USEREVENT+1事件给用户程序。

当前正有音乐在播放时,可以使用pygame.mixer.music.queue(filename)来指定下一个要播放的音乐文件,当前的音乐播放完成后自动开始播放指定的下一个。一次只能指定一个等待播放的音乐文件。

注意:同时只能播放一个音乐文件。音乐文件可以很大,系统以流的形式播放。

音效

要在游戏中播放碰撞、爆炸、语音等音效,需要使用pygame.mixer模块。这个模块支持同时播放多个音效文件,多个文件在多个不同的通道Channel中播放,一个通道一次只能播放一个音效文件。

使用pygame.init()进行全部模块初始化,或者只初始化音频部分pygame.mixer.init()可以这样查看总共有多少个通道pygame.mixer.get_num_channels()可以使用channel = pygame.mixer.Channel(i)取得第i个通道。或者使用channel = pygame.mixer.find_channel()

自动取得一个空闲的通道(没有音效正在播放的通道)。

使用sound = pygame.mixer.Sound(‘KDE_Startup_2.ogg)指定文件名载入一个音频文件,并创建一个Sound对象。音频文件可以是wav,ogg等格式。音频文件的内容会被全部载入到内存中。

使用channel.play(sound)在一个通道中播放一个音效。或者使用sound.play()自动找一个空闲的通道播放音效。

正在播放的音效可以使用sound.stop()停止音效sound的播放。或者用channel.stop()停止在通道channel中播放的音效。正在播放音效的通道还可以用channel.pause()暂停通道中的音效。暂停的音效还可以用channel.unpause()继续播放。使用channel.fadeout(time)来进行淡出,在time毫秒的时间内音量由初始值渐变为0,最后停止播放。对于一个通道可以用channel.get_busy()检查它是否正在播放音效。

当一个通道中的音效播放完成时,可以通过事件通知给用户程序。使用channel.set_endevent(pygame.USEREVENT + 1)来设置当音乐播放完成时发送pygame.USEREVENT+1事件给用户程序。

使用channel.queue(sound) 为正在播放音效的通道指定下一个要播放的音效。当前的音效播放完成后,下一个音效会自动播放。一个通道只能有一个等待播放的音效。

使用channel.set_volume(value)来设置通道中播放的音效的音量。使用sound.set_volume(value)来设置单个音效的音量。两者的取值范围都是0.0到1.0。音效播放的实际音量是通道音量和音效音量的乘积,比如通道音量0.5,音效音量0.6,则实际播放的音量为0.3。

注意:音效和音乐的区别是:音效要整个文件载入到Sound对象中才能播放,而音乐不用完全载入,而以流的方式播放。

Pygame学习笔记6:定时

定时

pygame中的时间是以毫秒(千分之一秒)表示的。

通过pygame.time.get_ticks函数可以获得pygame.init后经过的时间的毫秒数。

pygame.time.wait函数会暂停给定的时间。比如

pygame.time.wait(1000)

会暂停一秒钟。这个函数会休眠这个进程,使得其他程序可以共享处理器。一个程序即使只有休眠很少的毫秒数,就能够消耗非常少的处理器时间。pygame.time.delay函数也会使程序暂停给定的时间。这个函数会使用处理器(而不是休眠)以使这个等待比pygame.time.wait更加精确。这两个函数返回实际暂停的时间。

pygame.time.set_timer可以反复创建一个事件放在事件队列中。比如

pygame.time.set_timer(pygame.USEREVENT, 1000)

每隔1秒钟在事件队列中放一个pygame.USEREVENT事件。每一个事件类型可以有一个不同的定时器。要禁止一个事件的定时器,可以把对应的毫秒数设成0。

使用pygame.time.Clock可以更方便的控制游戏执行的速度。先使用

c = pygame.time.Clock()

创建一个Clock对象。然后可以调用

c.tick(30)

参数为游戏的帧速。这个函数会暂停一定的时间,保证两次tick调用之间间隔1/30秒。这可以帮助限制游戏运行的速度。通过每帧调用一次Clock.tick(30),这个程序就永远不会以超过每秒30帧的速度运行。通过调用tick_busy_loop方法也可以达到和tick相似的效果,区别是这个函数使用pygame.time.delay,会使用很多cpu来进行忙等,而定时也更精确一些。

通过

c.get_fps()

可以获得游戏运行的帧速。

Pygame学习笔记5:事件

事件系统

Pygame通过一个事件系统与用户进行交互,以及处理一些系统发生的事件。事件系统包括一个事件队列,其中每一项都是一个Event对象。所有的用户输入和一些系统事件,都会形成一个Event对象被添加到事件队列中。pygame.event模块提供了很多函数去访问和控制这个队列。
Event对象有各种不同的类型,比如KEYDOWN(键盘键按下)、MOUSEBUTTONDOWN(鼠标键按下)等,通过Event.type属性来区分。不同的类型的Event对象还有不同的其它属性。通过Event.dict属性来查看。常用的类型和对应的属性有:

事件 产生途径 参数

QUIT 用户按下关闭按钮 none

ATIVEEVENT Pygame被激活或者隐藏 gain, state

KEYDOWN 键盘被按下 unicode, key, mod

KEYUP 键盘被放开 key, mod

MOUSEMOTION 鼠标移动 pos, rel, buttons

MOUSEBUTTONDOWN 鼠标按下 pos, button

MOUSEBUTTONUP 鼠标放开 pos, button

JOYAXISMOTION 游戏手柄(Joystick or pad)移动 joy, axis, value

JOYBALLMOTION 游戏球(Joy ball)?移动 joy, axis, value

JOYHATMOTION 游戏手柄(Joystick)?移动 joy, axis, value

JOYBUTTONDOWN 游戏手柄按下 joy, button

JOYBUTTONUP 游戏手柄放开 joy, button

VIDEORESIZE Pygame窗口缩放 size, w, h

VIDEOEXPOSE Pygame窗口部分公开(expose)? none

USEREVENT 触发了一个用户事件 code

pygame.event.get函数可以从队列获取所有的消息,并把它们从队列中删除。

pygame.event.poll()提取并删除一个事件,如果队列是空的,这个函数会马上返回一个pygame.NOEVENT。

pygame.event.wait()提取一个事件,如果没有事件则会等待直到有事件发生。

pygame.event.clear()可以清空整个队列。

如果只关心某些类型的事件,可以用pygame.event.get(type),只取得队列中某种类型的事件。也可以用一个类型的列表,只取得某些类型的事件。pygame.event.peek(type)函数可以检查列表中是否有某种或者某些类型的事件,如果有就返回True。除此以外还可以用pygame.event.set_blocked阻止某些类型的事件进入事件队列,使用pygame.event.set_allowed来只允许某些类型的事件进入队列。

pygame.event.post函数可以往队列中添加一个事件。

用pygame.event.Event可以创建一个事件,比如:

e = pygame.event.Event(pygame.USEREVENT)

然后可以通过

pygame.event.post(e)

把这个事件添加到队列中,等待处理。在创建事件时可以添加自定义的属性。

在窗口方式下运行,通常只有活动的窗口才能获得用户键盘、鼠标的事件。如果希望在窗口方式下,不是活动状态也能获得事件,可以通过

pygame.event.set_grab(True)

来捕获所有输入。不过这样会阻止其它程序获得用户输入,使得除了这个游戏以外其它程序都不能正常运行。要解除这样的状态,可以执行

pygame.event.set_grab(False)

注意:这个慎用!!!

可以使用如下代码来测试事件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/env python

import pygame

pygame.init()

screen = pygame.display.set_mode((640, 480), 0, 32)

pygame.display.update()

while True:

for event in pygame.event.get():

print str(event)

if event.type == pygame.QUIT:

exit()

Pygame学习笔记4:字体

写字

相对于在Surface上画图,在Surface上写文字要复杂得多。

首先需要导入pygame.font模块并初始化。

import pygame.font

pygame.font.init()

选择字体

然后用pygame.font.get_fonts获取可用的字体的列表。

pygame.font.get_fonts()

它返回一个字体名字的列表。

然后再用字体名字列表中的一个名字可以创建一个字体对象。

font = pygame.font.SysFont(“monospace”, 12)

第一个参数指定字体的名字,第二个参数指定字体的大小。可选的第三个参数bold指定是否粗体,默认不是粗题。可选的地四个参数italic指定是否斜体,默认不是斜体。

如果是要使用自己给的字体文件,可以这样创建字体对象

font = pygame.font.Font(“uming.ttf”, 12)

第一个参数指定要载入的字体文件的路径,第二个参数指定字体的大小。

创建文字Surface

使用字体对象的Font.render函数可以创建一个Surface,里面包含写出来的文字。比如

font_surface = font.render(“www.xefan.com”, False, (255,0,0))

第一个参数是要写的文字,文字只能包含一行,换行符不会被画出来。第二个参数指定是否使用抗锯齿效果,如果是True字符会有光滑的边缘。第三个参数是字体的颜色。可选的第四个参数background用来指定文字背景的颜色。如果没有指定background,背景是透明的。返回创建的Surface,它上面包含了画出来的文字,它的大小是能容纳这些字的最小的大小。

要在已有的Surface上写字,只能先创建一个只包含文字的Surface,然后把它blit到已有的Surface上。比如:

surface.blit(font_surface, (100, 100))

最后用pygame.display.update()来显示。

显示中文说明:

要显示中文相对来说又要麻烦一些,首先你得有个可以使用中文的字体,如宋体、黑体等,或者你直接用中文TTF文件,然后文字使用unicode,即u”中文的文字”这种,最后不要忘了源文件里加上一句关于文件编码的注释。

Pygame学习笔记3:绘图

绘图

除了可以把事先画好的图片blit到Surface上以外,还可以在Surface上自行在Surface上绘制一些简单的图形,比如点、线、方、圆等。这个功能主要由pygame.draw模块完成。

首先导入pygame.draw模块。

import pygame.draw

如果已经用了import pygame,则pygame.draw模块也被自动导入了。

然后准备好要在上面绘制图形的Surface,比如

surface = pygame.display.set_mode((640, 480))

pygame.draw中函数的第一个参数总是一个surface,然后是颜色,再后会是一系列的坐标等。稍有些计算机绘图经验的人就会知道,计算机里的坐标,(0,0)代表左上角。而返回值是一个Rect对象,包含了绘制的领域,这样你就可以很方便的更新那个部分了。

函数 作用

rect 绘制矩形

polygon 绘制多边形(三个及三个以上的边)

circle 绘制圆

ellipse 绘制椭圆

arc 绘制圆弧

line 绘制线

lines 绘制一系列的线

aaline 绘制一根平滑的线

aalines 绘制一系列平滑的线

pygame.draw.rect

用法:pygame.draw.rect(Surface, color, Rect, width=0)

pygame.draw.rect在surface上画一个矩形,除了surface和color,rect接受一个矩形的坐标和线宽参数,如果线宽是0或省略,则填充。我们有一个另外的方法来画矩形——fill方法

pygame.draw.polygon

用法:pygame.draw.polygon(Surface, color, pointlist, width=0)

polygon就是多边形,用法类似rect,第一、第二、第四的参数都是相同的,只不过polygon会接受一系列坐标的列表,代表了各个顶点。

pygame.draw.circle

用法:pygame.draw.circle(Surface, color, pos, radius, width=0)

很简单,画一个圆。与其他不同的是,它接收一个圆心坐标和半径参数。

pygame.draw.ellipse

用法:pygame.draw.ellipse(Surface, color, Rect, width=0)

你可以把一个ellipse想象成一个被压扁的圆,事实上,它是可以被一个矩形装起来的。pygame.draw.ellipse的第三个参数就是这个椭圆的外接矩形。

pygame.draw.arc

用法:pygame.draw.arc(Surface, color, Rect, start_angle, stop_angle, width=1)

arc是椭圆的一部分,所以它的参数也就比椭圆多一点。但它是不封闭的,因此没有fill方法。start_angle和stop_angle为开始和结束的角度。

pygame.draw.line

用法:pygame.draw.line(Surface, color, start_pos, end_pos, width=1)

相信所有的人都能看明白。

pygame.draw.lines

用法:pygame.draw.lines(Surface, color, closed, pointlist, width=1)

closed是一个布尔变量,指明是否需要多画一条线来使这些线条闭合(感觉就和polygone一样了),pointlist是一个点的数组。

pygame.draw.aaline画抗锯齿的线段。

pygame.draw.aalines可以画多条连续的抗锯齿线段。

用法跟python.draw.line和pygame.draw.lines相似。

点操作

画点的方法和其它方法不太一样,用Surface.set_at方法完成画点的操作,比如:

surface.set_at((100, 100), (255,255,255))

第一个参数是点的坐标,第二个参数是颜色。

除了可以在Surface上画点,还可以用Surface.get_at读取Surface上像素的值。比如

color = surface.get_at((100, 100))

这个函数返回给定点的颜色值。

填充区域

Surface.fill方法可以用一种颜色填充一个矩形区域。比如

surface.fill((255,0,0), (100, 200, 100, 100))

第一个参数指定要填充的颜色,第二个参数指定填充的矩形区域。如果没有给定第二个参数,整个Surface会被填充。第二个参数会限制备填充的区域。这个函数会返回受影响的Surface区域。

Pygame学习笔记2:显示

首先使用了如下的语句创建一个窗口:

screen =pygame.display.set_mode((640, 480), 0, 32)

这里创建了一个640*480的黑窗口,现在可以往内面画内容。

读取和保存图片

使用pygame.image模块,可以对图像进行读取和保存。

使用pygame.image.load读取图像文件。

img = pygame.image.load(filename)

可以读取文件名为filename的图像文件,pygame会自动确定文件的类型(比如GIF或者BMP),一般来说支持JPG、PNG、GIF (non animated)、BMP、PCX、TGA (uncompressed)、TIF、LBM (及PBM)、PBM (及PGM, PPM)、XPM等。它返回一个包含图像的Surface,Surface的格式和原来的文件相同(包括颜色格式、透明色和alpha透明)。

使用pygame.image.save可以把图像保存到文件中。

pygame.image.save(img, filename)

这个函数可以把img这个Surface的内容保存为filename指定的图像文件,文件格式可以是BMP、TGA、PNG或者JPEG。如果文件扩展名不认识,默认保存为TGA格式。TGA和BMP格式都是非压缩的文件。

还有pygame.image.tostring、pygame.image.fromstring、pygame.image.frombuffer函数可以把图像序列化,即把图像保存在字符串中或者从字符串中读取图像。

变换

使用pygame.transform模块中的函数,可以对图像进行简单的变换。所有的这些函数都需要一个Surface参数指明要处理的图像,并生成一个新的图像表示处理后的结果,原来的图像不会被改变。

使用pygame.transform.flip可以上下左右翻转图像

使用pygame.transform.scale可以对图像进行缩放

使用pygame.transform.rotate可以对图像进行旋转

使用pygame.transform.rotozoom可以对图像进行缩放并旋转

使用pygame.transform.scale2x可以对图像进行快速的两倍大小的放大

使用pygame.transform.chop可以对图像进行裁减

转换Surfaces

通常你不用在意surface里的具体内容,不过也许你需要吧这些surface转换一下以获得更高的性能,

img2 =pygame.image.load(image_filename).convert()

mouse_cursor =pygame.image.load(image_filename).convert_alpha()

第一句是普通的转换,相同于display;第二句是带alpha通道的转换。如果你给convert或者conver_alpha一个surface对象作为参数,那么这个会被作为目标来转换。

块复制

一个图像复制到另一个上面

现在要将读取的图片画在屏幕上,可由blit函数来实现

Surface.blit(source, dest, area=None, special_flags = 0): return Rect

画的位置可以由dest参数指定。dest可以是一对坐标值,表示源Surface的左上角在这个Surface上的坐标。dest也可以是一个矩形,矩形的左上角作为blit的位置,而矩形的大小不影响blit。

有一个可选的area矩形参数,可以用来指定只画源Surface的一部分。

一个可选的special_flags参数,可以是BLEND_ADD、BLEND_SUB、BLEND_MULT、BLEND_MIN、BLEND_MAX。将来也可能有其它特殊标记添加进来。

函数返回的矩形表示受影响的像素的区域,不包括目标Surface以外的像素,也不包括剪切区域以外的像素。

例如:

screen.blit(img,(0,0))

然后使用pygame.display.update()来更新显示。

Pygame学习笔记1:起步

初始化
要使用pygame先要对其初始化。pygame的初始化是非常简单的,首先我们必须先导入(import)pygame这个包。

import pygame
from pygame.locals import *

第一行是必须的,它导入了pygame包中所有可用的模块。第二行是可选的,它把一些常量和函数放在global名字空间中。


必需注意的是,有些pygame模块是可选的,比如font模块。当你import pygame时,pygame会检查font模块是否存在。如果font模块存在,那么它会自动被导入为pygame.font。如果它不存在,pygame.font会被设置成None。


在用pygame前,必须先初始化。一般只要一句话就可以完成:

pygame.init()

执行这个语句,它会试着去初始化所有的pygame模块。并不是所有的模块都是需要初始化的,这个语句会自动去初始化那些需要初始化的模块。你也可以手动的去初始化各个模块,比如说要单独初始化display模块可以这样做:

pygame.display.init()

注意,如果执行pygame.init()初始化有错误,它不会给出异常。如果手动初始化单个模块,错误会导致抛出异常。任何必须初始化的模块都包含一个get_init()函数,来判断这个模块是否已经被初始化。

可以对任何模块多次调用init()函数而不会出错。


已经初始化的模块通常会有一个quit()函数来完成清理工作。没有必要显式的调用这个函数,因为pygame会在python退出的时候自动清理所有已经初始化的模块。

surface和屏幕

pygame最重要的部分就是surface。我们可以把surface看作是一张白纸。你可以对surface作很多操作。一个surface可以是任何大小,一个游戏可以有任意多surface。其中有一个surface是特别的,就是用pygame.display.set_mode()创建的display surface。它代表了屏幕,对它的任何操作会出现在用户的屏幕上。一个游戏只能有一个这样的surface,这是SDL的限制。


surface的大部分方法都不重要,只要学习其中的blit(), fill(), set_at()和get_at()就够用了。

display surface的初始化操作是这样的:

screen = pygame.display.set_mode((1024, 768))

或者

screen = pygame.display.set_mode((1024, 768), pygame.FULLSCREEN)

set_mode会返回一个Surface对象,代表了在桌面上出现的那个窗口,三个参数第一个为元祖,代表分 辨率(必须);第二个是一个标志位,具体意思见下表,如果不用什么特性,就指定0;第三个为色深。

标志位 功能

FULLSCREEN 创建一个全屏窗口

DOUBLEBUF 创建一个“双缓冲”窗口,建议在HWSURFACE或者OPENGL时使用

HWSURFACE 创建一个硬件加速的窗口,必须和FULLSCREEN同时使用

OPENGL 创建一个OPENGL渲染的窗口

RESIZABLE 创建一个可以改变大小的窗口

NOFRAME 创建一个没有边框的窗口


使用pygame.display.list_modes()可以查看当前设备支持的分辨率。

使用update函数把内容显示到屏幕上。

pygame.display.update()

如果使用DOUBLEBUF,你需要用flip函数。

pygame.display.flip()

Pygame学习笔记0:简介

学习Pygame也有一段时间了,现在整理一下笔记作为备忘。

介绍

pygame是主要构筑在SDL库基础上的一组Python模块的集合,它使我们能够用Python语言来创建功能完整的游戏和多媒体程序。pygame是高度括平台可移植的,在任何SDL支持的平台上都可以运行(几乎可以在任何平台和操作系统上运行)。

注:SDL(Simple DirectMedia Layer)是一个跨平台的多媒体库,可以用来访问底层的音频、键盘、鼠标、摇杆、3D硬件(通过OpenGL)以及2D视频缓冲。它被用在MPEG播放软件、模拟器和很多流行的游戏中,包括获得大奖的Linux版的”Civilization: Call To Power”。

pygame是自由、免费的,以GNU LGPL 2.1协议发布。这协议基本上就让你可以在你的任何项目中使用pygame。你可以用它来创建开源、自由、免费、共享或者商业游戏。但是如果你要增加和改变pygame本身的功能,你必须以一种LGPL兼容的协议来发布这种修改。

而examples子目录中的程序属于公共域软件。

安装

要学习Pygame需要先安装Python和Pygame。

Python下载地址:http://python.org/download/

Pygame下载地址:http://www.pygame.org/download.shtml

我用的是Python 2.6.6和Pygame 1.9.1release

Pygame有很多的模块,下面是各模块一览:

模块名 功能

pygame.cdrom 访问光驱

pygame.cursors 加载光标

pygame.display 访问显示设备

pygame.draw 绘制形状、线和点

pygame.event 管理事件

pygame.font 使用字体

pygame.image 加载和存储图片

pygame.joystick 使用游戏手柄或者 类似的东西

pygame.key 读取键盘按键

pygame.mixer 声音

pygame.mouse 鼠标

pygame.movie 播放视频

pygame.music 播放音频

pygame.overlay 访问高级视频叠加

pygame 就是我们在学的这个东西了……

pygame.rect 管理矩形区域

pygame.sndarray 操作声音数据

pygame.sprite 操作移动图像

pygame.surface 管理图像和屏幕

pygame.surfarray 管理点阵图像数据

pygame.time 管理时间和帧信息

pygame.transform 缩放和移动图像

注:有些模块可能在某些平台上可能不存在。

PyGTK for Win32集成安装包

这个是国外的一强人制作的,支持Python2.5~2.7。
该安装包包含如下内容:

PyGTK 2.17.0 with numpy support

PyGobject 2.21.5

PyCairo 1.8.10

PyGtkspell, PyGTKhtml2, PyGDL 2.25.3

PyGDA 2.29.1

PyGST (Python Gstreamer) 0.10.20

PyWebkitGTK 1.18

PyClutter 1.3.2 with gst and gtk binding

PyGTKGlExt 1.1.0

PyGoocanvas 0.14.1

PyGTKSourceview 2.10.0

PyGTKImageview 1.2.0

PyRSVG 2.30

PyScintilla 1.99

PMing 4.4

Python Poppler 0.12 GPL

VIPSCC 7.24

安装之前请卸载之前的版本。

2011-07-02
pygtk_aio-2011_win32_installer_py25-27-rev5.exe
md5:32c0558754ae06e14d5db466037ce174
下载地址: http://u.115.com/file/aqzkqxd3

2011-03-30
pygtk_aio-2011_win32_installer_py25-27-rev4.exe
md5:eb80322f7da800196cb77d79d7e7d6a2
下载地址:http://u.115.com/file/clgslsma

pygtk_aio-2011_win32_installer-rev2.exe
下载地址:http://u.115.com/file/aqzknhvq

原作者博客:http://opensourcepack.blogspot.com/2011/01/conservative-all-in-one-pygtk-installer.html