views:

459

answers:

3

I've searched on this, but nothing has what I'm looking for.

http://www.mail-archive.com/[email protected]/msg10529.html -- Nobody answered him. This is exactly what I'm experiencing. When I set the foreground on a graphics context, it doesn't seem to actually change.

I've been through the tutorial and FAQ, but neither say much. They either just use the black and white contexts or they give you broken links. I'm left thinking maybe it's a bug. But the kid in me says I'm just missing something and I keep ignoring the fact I have a working alternative. This would be better though. And the further I get into this, the more I'm going to need these contexts and colors.

Here's my code snippet.

def CreatePixmapFromLCDdata(lcdP, ch, widget):
    width = lcdP.get_char_width()
    height = lcdP.get_char_height()

    # Create pixmap
    pixmap = gtk.gdk.Pixmap(widget.window, width, height)

    # Working graphics contexts, wrong color
    black_gc = widget.get_style().black_gc
    white_gc = widget.get_style().white_gc

    char_gc = widget.window.new_gc()
    colormap = char_gc.get_colormap()

    bg_color = NewColor(text="#78a878", colormap=colormap)

    print "Before", char_gc.foreground.red, char_gc.foreground.green, char_gc.foreground.blue
    char_gc.set_foreground(bg_color)
    print "AFter", char_gc.foreground.red, char_gc.foreground.green, char_gc.foreground.blue

    fg_color = NewColor(text="#113311", colormap=colormap)

    pixmap.draw_rectangle(char_gc, True, 0, 0, width, height)
    char_gc.foreground = fg_color
    for j in range(lcdP.dots['y']):
        k = lcdP.pixels['y']*j
        for i in range(lcdP.dots['x']):
            if 1<<(lcdP.dots['x']-1-i) & ch[j] == 0: continue

            m = i*lcdP.pixels['y']

            for jj in range(k, k+lcdP.pixels['y']-1):
                for ii in range(m+1, m+lcdP.pixels['x']):
                    pixmap.draw_point(char_gc, ii, jj)
    return pixmap

I thought maybe it was the way I was allocating the colors. As you see in the snippet, I've used the graphic context's own colormap. I've tried different colormaps, this being the latest. I've even tried an unallocated color. Notice the white_gc and black_gc graphics contexts. When I use those I'm able to draw black on a white background fine. Otherwise (with a created context) everything's black, fg and bg. When I change white's foreground color, it always comes out black.

Here's the output. Notice the color doesn't change very much. I'd say it didn't change, or at least not enough to matter visually.

Before 6 174 60340
After 5 174 60340

Here's how I allocate the colors.

def NewColor(red=0, green=0, blue=0, text=None, colormap=None):
    if text == None:
        c = gtk.gdk.Color(red, green, blue)
    else:
        c = gtk.gdk.color_parse(text)
    if colormap == None:
        colormap = gtk.gdk.colormap_get_system()
    colormap.alloc_color(c)
    return c
+2  A: 

I've had some trouble with Drawable and GC in the past. This answer got me started on the way to a solution. Here's a quick example that uses a custom colour gc to draw some squares:

import gtk

square_sz = 20
pixmap = None
colour = "#FF0000"
gc = None

def configure_event( widget, event):
    global pixmap
    x, y, width, height = widget.get_allocation()
    pixmap = gtk.gdk.Pixmap(widget.window, width, height)
    white_gc = widget.get_style().white_gc
    pixmap.draw_rectangle(white_gc, True, 0, 0, width, height)
    return True

def expose_event(widget, event):
    global pixmap
    if pixmap:
     x , y, w, h = event.area
     drawable_gc = widget.get_style().fg_gc[gtk.STATE_NORMAL]
     widget.window.draw_drawable(drawable_gc, pixmap, x, y, x, y, w, h)
    return False

def button_press_event(widget, event):
    global pixmap, square_sz, gc, colour
    if event.button == 1 and pixmap:
     x = int(event.x / square_sz) * square_sz
     y = int(event.y / square_sz) * square_sz
     if not gc:
      gc = widget.window.new_gc()
      gc.set_rgb_fg_color(gtk.gdk.color_parse(colour))
     pixmap.draw_rectangle(gc, True, x, y, square_sz, square_sz)
     widget.queue_draw_area(x, y, square_sz, square_sz)

    return True

if __name__ == "__main__":
    da = gtk.DrawingArea()
    da.set_size_request(square_sz*20, square_sz*20)

    da.connect("expose_event", expose_event)
    da.connect("configure_event", configure_event)
    da.connect("button_press_event", button_press_event)

    da.set_events(gtk.gdk.EXPOSURE_MASK | gtk.gdk.BUTTON_PRESS_MASK)

    w = gtk.Window()
    w.add(da)
    w.show_all()
    w.connect("destroy", lambda w: gtk.main_quit())

    gtk.main()

Hope it helps.

igkuk7
Well, set_rgb_fg_color works. I never saw that method in any of the documentation. Thanks for the tip. It works now.
Scott
thank god. i was just having the exact same problem. why would you have set_foreground that doesn't work, but an undocumented set_rgb_fg_color that does... sigh..
Claudiu
A: 

Same problem here. I submitted this bug report if anyone would like to confirm it.

Chris
+1  A: 

The problem is that the NewColor() function is returning an unallocated color c. colormap.alloc_color() returns a gtk.gdk.Color which is the allocated color. To fix things the last line in NewColor() should be:

return colormap.alloc_color(c)
zeke