Kim Adil wrote:
> I once wrote a gtk program in C that displayed about 30 animations on a
> drawing area and they moved around the screen, and performance was
> excellent. The drawingarea size was 1600x1200 and the animations were
> very smooth.
>
> I have started to write a similar app using pygtk in a more object
> oriented way, and the drawing area size really seems to have a large
> impact on performance. When the drawing area is 100x100, anims are
> smooth. If the drawing area is dragged to 1000x1000 the frame rate drops
> very quickly. Is this to be expected with the python being interpreted,
> or is it just that my code is inefficient. See sample below (requires 2
> animated gif files a.gif and a2.gif, just substitute any from the web 
> for demonstartion, and a glade file attached):
>
>
> #!/usr/bin/env python
> import sys
> import pygtk
> import glib
> import gtk
> import gtk.glade
> # main window to display objects in motion
>
> i=1
> class MainWin:
>     def __init__(self):
>         self.gladefile = "hv.glade"
>         self.wTree = gtk.glade.XML(self.gladefile, "main_win")
>         dic = {"on_drawingarea1_expose_event" : self.expose,
>                "on_drawingarea1_configure_event": self.configure,
>                }
>         self.wTree.signal_autoconnect(dic)
>         self.window = self.wTree.get_widget("main_win")
>         self.da = self.wTree.get_widget("drawingarea1")
>         self.window.show_all()
>         x, y, width, height = self.da.get_allocation()
>         self.pixmap = gtk.gdk.Pixmap(self.da.window, width, height)
>         self.machlist = []
>         self.setup_objects()
>         glib.timeout_add(30, self.draw_objects)
>
>     def setup_objects(self):
>         self.machlist.append(Object('t1','v','stopped',10,10,'a.gif'))
>         
> self.machlist.append(Object('t2','v','travelling',300,10,'a2.gif'))
>         self.machlist.append(Object('t3','v','stopped',100,300,'a.gif'))
>         self.machlist.append(Object('t4','v','stopped',600,600,'a2.gif'))
>         self.machlist.append(Object('t5','v','stopped',100,60,'a.gif'))
>         self.machlist.append(Object('t6','f','stopped',60,100,'a.gif'))
>         
> self.machlist.append(Object('t7','f','travelling',100,100,'a.gif'))
>
>     def draw_objects(self):
>         x, y, width, height = self.da.get_allocation()
>         self.pixmap = gtk.gdk.Pixmap(self.da.window, width, height)
>         self.pixmap.draw_rectangle(self.da.get_style().white_gc,True, 0,
> 0, width, height)
>         for object in self.machlist:
>
> self.pixmap.draw_pixbuf(self.da.get_style().fg_gc[gtk.STATE_NORMAL],object.pb,
>  
>
> 0, 0, object.x,object.y)
Add this line:
           self.da.queue_draw_area(x, y, width, height)
>         return True
>     def expose(self,a,b):
>         x, y, width, height = self.da.get_allocation()
>
> self.da.window.draw_drawable(self.da.get_style().fg_gc[gtk.STATE_NORMAL],self.pixmap,
>  
>
> x, y, x, y, width, height)
>         self.da.queue_draw_area(x, y, width, height)
Remove the above line.
>         return False
>
>     def configure(self,a,b):
>         x, y, width, height = self.da.get_allocation()
>
> self.da.window.draw_drawable(self.da.get_style().fg_gc[gtk.STATE_NORMAL],self.pixmap,
>  
>
> x, y, x, y, width, height)
>         return False
>
>     def cleanup(self):
>         for object in self.machlist:
>             glib.source_remove(object.timeout)
>
>     def list_objects(self):
>         self.draw_objects()
>         for object in self.machlist:
>
> self.pixmap.draw_pixbuf(self.da.get_style().fg_gc[gtk.STATE_NORMAL],object.pb,
>  
>
> 0, 0, 0, 0)
>         #self.da.queue_draw()
> class Object:
>     def __init__(self,name,model,state,x,y,anim):
>         self.name=name
>         self.model=model
>         self.state=state
>         self.x=x
>         self.y=y
>         self.anim=anim
>         self.image='l'
>         self.frame=0
>         self.imagef = gtk.Image()
>         self.pixbufanim = gtk.gdk.PixbufAnimation(anim)
>         print 'width %d - height
> %d'%(self.pixbufanim.get_width(),self.pixbufanim.get_height())
>         self.pbiter = self.pixbufanim.get_iter()
>         print 'delay time %d'%(self.pbiter.get_delay_time())
>         self.pb=self.pbiter.get_pixbuf()
>         self.t=glib.timeout_add(self.pbiter.get_delay_time(),
> self.update_pb)
>
>     def update_pb(self):
>         self.pbiter.advance()
>         self.pb=self.pbiter.get_pixbuf()
>         self.t=glib.timeout_add(self.pbiter.get_delay_time(),
> self.update_pb)
>         return False
>
>
> print 'create mainwin'
> m=MainWin()
> gtk.main()
>
I think the program is generating too many expose events and too many 
draw_pixbuf calls are slowing down the animations when a large pixbuf 
draw is needed.

John
_______________________________________________
pygtk mailing list   pygtk@daa.com.au
http://www.daa.com.au/mailman/listinfo/pygtk
Read the PyGTK FAQ: http://faq.pygtk.org/

Reply via email to