用Python、Gtk和Cairo动画过渡的方法?
大家好
我看到一些教程在讲怎么用PyGtk制作动画,其中最好的一个是这个:
https://cairographics.org/cookbook/animationrotation/
这个教程使用了 gobject.timeout_add()
来设置一个时钟,不断刷新动画。
不过我想做的是有限的动画,也就是说我希望能通过点击按钮、复选框或其他东西来触发动画。
举个例子,我可以有一个窗口,里面有一个按钮和一个绘图区域,绘制了一个球。点击按钮后,球会上下移动,然后停下来。如果我再点击一次,球就会重复这个动作。
在另一个场景中,球可能在屏幕的左边。当我切换复选框时,球会(不是瞬间,而是慢慢移动)向右移动。如果我取消勾选,球就会回到原来的位置。
我不打算使用其他任何东西,只想用纯粹的Cairo/Gtk(不使用Clutter、OpenGL或PyGame),因为我觉得这样是可行的,我也想继续学习Gtk,以便将来用简单的一文件脚本做一些GUI的小把戏。
由于这个问题涉及的内容比较广泛,我觉得不需要添加代码,但如果有人觉得加代码会更好,我可以编辑这个问题来放一些代码。
谢谢大家的阅读和帮助!Cairo/Gtk真棒!
编辑:在Jeremy Flores的详细解释后,我写出了这段代码,虽然没什么用(每次点击按钮球都会向右移动,直到掉出窗口),但包含了一些可以用来构建更有创意和实用的东西的元素。如果有人(包括Jeremy)对这段代码有任何意见,特别是关于去掉不必要的部分,我非常乐意听取。谢谢!
#!/usr/bin/env python
import gtk, gobject
from math import pi
class Canvas(gtk.DrawingArea):
def __init__(self):
super(Canvas, self).__init__()
self.connect("expose_event", self.expose)
self.set_size_request(400,400)
self.x = 20
self.y = 20
self.counter = 0
def movealittle(self):
self.x += 1
self.counter += 1
self.queue_draw()
if self.counter <= 20:
return True
elif self.counter > 20:
self.counter = 0
return False
def expose(self, widget, event):
cr = widget.window.cairo_create()
rect = self.get_allocation()
w = rect.width
h = rect.height
cr.arc(self.x, self.y, 10, 0, 2*pi)
cr.fill()
def runanimation(widget):
gobject.timeout_add(5, canvas.movealittle)
print "runanimation call"
button = gtk.Button("Move")
button.connect("clicked", runanimation)
window = gtk.Window()
canvas = Canvas()
panel = gtk.VBox()
window.add(panel)
panel.pack_start(canvas)
panel.pack_start(button)
window.set_position(gtk.WIN_POS_CENTER)
window.show_all()
gtk.main()
1 个回答
gobject.timeout_add() 可以用来做有限的动画。你设置的回调函数会一直被调用,直到它返回 False,这时你的方法就不会再被调用了。
举个例子,如果你想让一个球动画持续 5 秒钟,你需要自己去判断动画已经进行了多长时间,然后一旦超过 5 秒,你的方法就返回 False 来结束动画。当你想要重新开始动画时,只需再次用 timeout_add 注册回调,并重置你的时间计数器。
想了解更多信息,可以查看这个链接:http://www.pygtk.org/pygtk2reference/gobject-functions.html#function-gobject--timeout-add。