|
|
|
|||||||||||
Drawing with Cairo without flickerDecember
30
(py)Gtk provides a quick way to get a cairo context using the gtk.DrawingArea widget, this widget let you draw everythin you want into your application using the widget.window drawable area. It help you to create custom widgets (you can also use this with buttons or any other widget), the problem with the usage of this context is that everything you ask it to draw it will draw it as soon as it can. If you draw several lines or you draw the same thing very often (an animation for example) your draw may flick, making your application looks ugly. There is an easy way to avoid this, using a surface to draw and when you are done put your draw into the context using the set_source_surface method. In the next example you have a windows, with a custom "progressbar" using gtk.DrawingArea and a slide that is supposed to change the value of the progressbar but I'm so lazy to move a slide that let the computer do the work :-). The trick is this part of the code:
def do_expose(self, widget, event): x,y,w,h = self.allocation surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w,h) context = cairo.Context(surface) #cleaning rectangle = context.rectangle(x,y,w,h) context.set_source_rgb(1,1,1) context.fill() value = (self.value / 100)*w rectangle = context.rectangle(x,y,value,h) context.set_source_rgb(0.2,0.5,0.8) context.fill() cr = self.window.cairo_create() cr.set_source_surface(surface) cr.paint() return True
We create a surface using cairo.ImageSurface and then create a cairo context from it, draw on that context and at the end use the widget.window.cairo_create to create a context for the drawing_area and use set_source_surface to get all the stuff
#!/usr/bin/env python import gtk import cairo import random import gobject class progressbar(gtk.DrawingArea): def __init__(self): gtk.DrawingArea.__init__(self) self.connect('expose-event', self.do_expose) self.value = 0 self.set_property('events', gtk.gdk.EXPOSURE_MASK) def do_expose(self, widget, event): x,y,w,h = self.allocation surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w,h) context = cairo.Context(surface) #cleaning rectangle = context.rectangle(x,y,w,h) context.set_source_rgb(1,1,1) context.fill() value = (self.value / 100)*w rectangle = context.rectangle(x,y,value,h) context.set_source_rgb(0.2,0.5,0.8) context.fill() cr = self.window.cairo_create() cr.set_source_surface(surface) cr.paint() return True def set_value(self, value): self.value = value self.emit('expose-event', gtk.gdk.Event(gtk.gdk.EXPOSE)) def change_value(scale, progres): progress.set_value(scale.get_value()) def random_change(scale): r = random.randint(50,100) scale.set_value(r) return True window = gtk.Window() window.set_size_request(640,480) window.set_position(gtk.WIN_POS_CENTER) window.connect('destroy', gtk.main_quit) vbox = gtk.VBox() window.add(vbox) progress = progressbar() progress.set_size_request(100,100) vbox.pack_start(progress, False, False, 2) adjustment = gtk.Adjustment(value=0, lower=0, upper=100) scale = gtk.HScale(adjustment) scale.connect('value-changed', change_value, progress) vbox.pack_start(scale, False, False, 2) gobject.idle_add(random_change, scale) window.show_all() gtk.main()
Comment XML feeds: RSS | Atom
|
|
Recent Comments On BlogMarco Antonio Islas Cruz on Marco Antonio Islas Cruz on Marco Antonio Islas Cruz on Getting ready Marco Antonio Islas Cruz on Python: Create win32 services using Python and py2exe jopython@gmail.com on Python: Create win32 services using Python and py2exe yodenuevo on Holy Shit! markuz on Holy Shit! yo on Holy Shit! Gustavo on Things that happen last week Marco Antonio Islas Cruz on Christine: rola_christine.py |
|||||||||
|
|
|||||||||||
Leave a Comment