2010-03-05 133 views

回答

5
#!/usr/bin/env python 

import gtk 

def rounded_rectangle(cr, x, y, w, h, r=20): 
    # This is just one of the samples from 
    # http://www.cairographics.org/cookbook/roundedrectangles/ 
    # A****BQ 
    # H  C 
    # *  * 
    # G  D 
    # F****E 

    cr.move_to(x+r,y)      # Move to A 
    cr.line_to(x+w-r,y)     # Straight line to B 
    cr.curve_to(x+w,y,x+w,y,x+w,y+r)  # Curve to C, Control points are both at Q 
    cr.line_to(x+w,y+h-r)     # Move to D 
    cr.curve_to(x+w,y+h,x+w,y+h,x+w-r,y+h) # Curve to E 
    cr.line_to(x+r,y+h)     # Line to F 
    cr.curve_to(x,y+h,x,y+h,x,y+h-r)  # Curve to G 
    cr.line_to(x,y+r)      # Line to H 
    cr.curve_to(x,y,x,y,x+r,y)    # Curve to A 

def expose(canvas, event): 
    # Create cairo context 
    cr = canvas.window.cairo_create() 

    # Restrict drawing to the exposed area, so that 
    # no unnecessary drawing is done 
    cr.rectangle(event.area.x, event.area.y, 
       event.area.width, event.area.height) 
    cr.clip() 

    rounded_rectangle(cr, 100, 100, 100, 100) 
    cr.set_line_width(4.0) 
    cr.set_source_rgb(1.0, 0.0, 0.0) 
    cr.stroke_preserve() 
    cr.set_source_rgb(1.0, 0.5, 0.5) 
    cr.fill() 

# Construct window 
window = gtk.Window() 
canvas = gtk.DrawingArea() 
canvas.set_size_request(300, 300) 
canvas.connect('expose-event', expose) 
window.connect('delete-event', gtk.main_quit) 
window.add(canvas) 
window.show_all() 

gtk.main() 
+1

如果你要畫這幾次(可以說...一個動畫),你應該使用雙緩衝,以避免輕彈,請檢查我的博客上的代碼:http:// tinyurl .COM/38vpgtw – markuz 2010-05-07 05:56:42

1

巧合的是,我已經把,我自己,同樣的教程頁面上的代碼片段引用@ptomato的代碼。優點是使用arc而不是curve,因爲它會產生真正的圓弧角。這裏是:

def draw_rounded(cr, area, radius): 
    """ draws rectangles with rounded (circular arc) corners """ 
    from math import pi 
    a,b,c,d=area 
    cr.arc(a + radius, c + radius, radius, 2*(pi/2), 3*(pi/2)) 
    cr.arc(b - radius, c + radius, radius, 3*(pi/2), 4*(pi/2)) 
    cr.arc(b - radius, d - radius, radius, 0*(pi/2), 1*(pi/2)) # ;o) 
    cr.arc(a + radius, d - radius, radius, 1*(pi/2), 2*(pi/2)) 
    cr.close_path() 
    cr.stroke() 

################################################################ 

### EXAMPLE 
import cairo, Image 

w,h = 800, 600 
offset = 100 
fig_size = (w,h) 

# an area with coordinates of 
# (top, bottom, left, right) edges in absolute coordinates: 
inside_area = (offset, w-offset, offset, h-offset) 

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, *fig_size) 
cr = cairo.Context(surface) 
cr.set_line_width(3) 
cr.set_source_rgb(1,1,1) 

draw_rounded(cr, inside_area, 150) 

im = Image.frombuffer("RGBA", 
         fig_size, 
         surface.get_data(), 
         "raw", 
         "BGRA", 
         0,1) 
im.show()