开发者

rounded rectangle in pygtk

what is the best way 开发者_运维技巧to draw a rounded rectangle in a pygtk application


#!/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()


Coincidentally, I have put, myself, a code snippet on the same tutorial page cited in @ptomato 's code. The advantage is the use of arc instead of curve, because it will create true circular arc corners. Here it goes:

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()


Probably pycairo

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜