Graphics glitch when drawing to a Cairo context obtained from a gtk.DrawingArea inside a gtk.Viewport.
Posted
by
user410023
on Stack Overflow
See other posts from Stack Overflow
or by user410023
Published on 2011-01-16T00:42:55Z
Indexed on
2011/01/16
0:53 UTC
Read the original article
Hit count: 319
I am trying to redraw the part of the DrawingArea that is visible in the Viewport in the expose-event handler. However, it seems that I am doing something wrong with the coordinates that are passed to the event handler because there is garbage at the edge of the Viewport when scrolling. Can anyone tell what I am doing wrong? Here is a small example:
import pygtk
pygtk.require("2.0")
import gtk
from numpy import array
from math import pi
class Circle(object): def init(self, position = [0., 0.], radius = 0., edge = (0., 0., 0.), fill = None): self.position = position self.radius = radius self.edge = edge self.fill = fill def draw(self, ctx): rect = array(ctx.clip_extents()) rect[2] -= rect[0] rect[3] -= rect[1] center = rect[2:4] / 2 ctx.arc(center[0], center[1], self.radius, 0., 2. * pi) if self.fill != None: ctx.set_source_rgb(*self.fill) ctx.fill_preserve() ctx.set_source_rgb(*self.edge) ctx.stroke()
class Scene(object): class Proxy(object): directory = {} def init(self, target, layers = set()): self.target = target self.layers = layers Scene.Proxy.directory[target] = self
def __init__(self, viewport):
self.objects = {}
self.layers = [set()]
self.viewport = viewport
self.signals = {}
def draw(self, ctx):
x = self.viewport.get_hadjustment().value
y = self.viewport.get_vadjustment().value
ctx.set_source_rgb(1., 1., 1.)
ctx.paint()
ctx.translate(x, y)
for obj in self:
obj.draw(ctx)
def add(self, item, layer = 0):
item = Scene.Proxy(item, layers = set((layer,)))
assert(hasattr(item.target, "draw"))
assert(isinstance(layer, int))
item.layers.add(layer)
while not layer < len(self.layers):
self.layers.append(set())
self.layers[layer].add(item)
if not item in self.objects:
self.objects[item] = set()
self.objects[item].add(layer)
def remove(self, item, layers = None):
item = Scene.Proxy.directory[item]
if layers == None:
layers = self.objects[item]
for layer in layers:
layer.remove(item)
item.layers.remove(layer)
if len(item.layers) == 0:
self.objects.remove(item)
def __iter__(self):
for layer in self.layers:
for item in layer:
yield item.target
class App(object): def init(self): signals = { "canvas_exposed": self.update_canvas, "gtk_main_quit": gtk.main_quit } self.builder = gtk.Builder() self.builder.add_from_file("graphics_glitch.glade") self.window = self.builder.get_object("window") self.viewport = self.builder.get_object("viewport") self.canvas = self.builder.get_object("canvas") self.scene = Scene(self.viewport) signals.update(self.scene.signals) self.builder.connect_signals(signals) self.window.show()
def update_canvas(self, widget, event):
ctx = self.canvas.window.cairo_create()
self.scene.draw(ctx)
ctx.clip()
if name == "main": app = App() scene = app.scene scene.add(Circle((0., 0.), 10.)) gtk.main()
And the Glade file "graphics_glitch.glade":
<?xml version="1.0"?>
<interface>
<requires lib="gtk+" version="2.16"/>
<!-- interface-naming-policy project-wide -->
<object class="GtkWindow" id="window">
<property name="width_request">200</property>
<property name="height_request">200</property>
<property name="visible">True</property>
<signal name="destroy" handler="gtk_main_quit"/>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hadjustment">h_adjust</property>
<property name="vadjustment">v_adjust</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<child>
<object class="GtkViewport" id="viewport">
<property name="visible">True</property>
<property name="resize_mode">queue</property>
<child>
<object class="GtkDrawingArea" id="canvas">
<property name="width_request">640</property>
<property name="height_request">480</property>
<property name="visible">True</property>
<signal name="expose_event" handler="canvas_exposed"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<object class="GtkAdjustment" id="h_adjust">
<property name="lower">-1000</property>
<property name="upper">1000</property>
<property name="step_increment">1</property>
<property name="page_increment">25</property>
<property name="page_size">25</property>
</object>
<object class="GtkAdjustment" id="v_adjust">
<property name="lower">-1000</property>
<property name="upper">1000</property>
<property name="step_increment">1</property>
<property name="page_increment">25</property>
<property name="page_size">25</property>
</object>
</interface>
Thanks!
--Dan
© Stack Overflow or respective owner