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: 316

Filed under:
|
|
|

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

Related posts about python

Related posts about gtk