PyGTK中的圆角矩形

0 投票
3 回答
2398 浏览
提问于 2025-04-15 20:02

在pygtk应用程序中,绘制圆角矩形的最佳方法是什么?

3 个回答

0

可能是 pycairo

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

在编程中,有时候我们会遇到一些问题,想要找到解决方案。StackOverflow是一个很好的地方,大家可以在这里提问和回答问题。这里的内容通常是关于编程的各种技术细节和经验分享。

当你在StackOverflow上看到一个问题时,通常会有很多人给出不同的答案。每个答案可能会提供不同的解决方法,或者解释某个技术概念。你可以根据自己的需求选择最适合的答案。

有些回答可能会包含代码示例,这些代码可以帮助你更好地理解问题的解决方案。记得查看这些代码块,因为它们通常是解决问题的关键。

总之,StackOverflow是一个学习和解决编程问题的好地方,大家可以在这里互相帮助,分享知识。

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

撰写回答