使用GTK +平滑动画

时间:2009-02-22 22:08:36

标签: animation gtk pygtk

我正在创建一个网络动画师(类似于nam,如果您以前使用过它)。

基本上,我在GTK + DrawingArea上有节点表示小点,我更新这些节点的位置并重新绘制一个循环中的DrawingArea。

生成的动画很快,但不流畅(有很多闪烁)。这可能是因为我在每帧之前用一个纯色填充DrawingArea。

您认为我怎么能最好地解决这个问题?我应该预先渲染帧到Pixbufs吗?有更好的解决方案吗?

这是我当前的绘图代码(使用PyGTK):

rect  = self.drawing_area.get_allocation()
style = self.drawing_area.get_style()

pos   = [n.position_at(self.t) for n in self.nodes]

self.drawing_area.window.draw_rectangle(style.bg_gc[gtk.STATE_NORMAL], True,
                                        0, 0, rect.width, rect.height)

for p in pos:
    self.drawing_area.window.draw_arc(style.fg_gc[gtk.STATE_NORMAL], True,
                                      rect.width  * (p.x / 2400.0) - NODE_SIZE/2,
                                      rect.height * (p.y / 2400.0) - NODE_SIZE/2,
                                      NODE_SIZE, NODE_SIZE,
                                      0, 64 * 360)

其中self.t是当前时间,在循环中递增。

2 个答案:

答案 0 :(得分:5)

我更改了代码以将帧渲染到Pixmap上,并将DrawingArea替换为Image。

虽然这解决了闪烁问题,但现在CPU使用率达到了顶峰。动画仍然很快,但我不认为这种方法是可扩展的。

我想是时候进行一些优化了。

UPDATE:事实证明,使用带有Image的expose-event不是一个好主意。 CPU使用率恢复正常。

答案 1 :(得分:2)

关于揭露事件处理,请查看有关Cairo + Gtk的动画的第一段:P

  

使用Cairo和GTK +的多线程动画
  复杂的动画   cairo和GTK +会导致界面滞后。这是因为   gtk_main()线程在单个循环中运行。所以,如果你的do_draw()   函数实现了一个复杂的绘图命令,并被调用   来自gtk_main()线程(比如on_window_expose_event()   函数),你的gtk代码的其余部分将被阻塞,直到   do_draw()函数完成。因此,菜单项,鼠标   点击,甚至关闭按钮事件将很慢处理和   你的界面会感觉很迟钝。

     

一种解决方案是将所有处理器密集型绘图移交给a   单独的线程,从而释放gtk_main()线程来响应   事件

http://cairographics.org/threaded_animation_with_cairo/