Skip to main content
 首页 » 编程设计

python之透明小部件背景

2025年05月04日9zfyouxi

我是 pygtk 的新手。我正在寻找一种方法来创建使用父背景作为自己背景的自定义小部件 像这样的 https://fbcdn-sphotos-e-a.akamaihd.net/hphotos-ak-prn1/31617_421363141269410_1875576801_n.jpg

如何获取父位图并将其用作自己的位图?

class RoundRectPanel(gtk.DrawingArea, PanelBase): 
    """ 
    Panel That represents 
    """ 
    def __init__(self): 
        super(ProximityPanel, self).__init__() 
 
    def initialize(self): 
        super(RoundRectPanel, self).initialize() 
 
        self.set_size_request(340, 300) 
        self.connect('expose-event', self.expose) 
 
    def terminate(self): 
        pass 
 
    def rounded_rectangle(self, cr, x, y, w, h, r=20): 
        #   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(self, canvas, event): 
        # Create cairo context 
        cr = canvas.window.cairo_create() 
 
        # TODO: 1. GET PARENT background 
        # 2. set it as canvas background 
 
        # 3. draw on it 
        self.rounded_rectangle(cr, 0, 0, 340, 300) 
        cr.stroke_preserve() 
        cr.set_source_rgba(1.0, 1.0, 1.0, 0.5) 
        cr.fill() 

请您参考如下方法:

目前找到了解决方法,它需要自定义小部件与他的父窗口(绘制背景图像的地方)进行通信。 CustomWidget 需要来自父级的背景图像信息(窗口中的文件名和图像位置)

class CustomWidget(gtk.DrawingArea): 
def __init__(self, parent): 
    super(CustomWidget, self).__init__() 
    self.set_size_request(340, 300) 
    self._parent = parent 
 
    self.connect('expose-event', self._expose_event) 
 
def _expose_event(self, widget, event): 
    cr = widget.window.cairo_create() 
 
    self.draw_context(cr, widget) 
 
def draw_context(self, cr, widget): 
    ctx = cr 
    x, y, width, height = widget.allocation 
 
    # parent window should have file name that is used as a background 
    pixbuf = gtk.gdk.pixbuf_new_from_file(self._parent.file) 
    ctx.save() 
    # copy particular image region where your custom widget is located 
    ctx.set_source_pixbuf(pixbuf, (-x) + self._parent.image.allocation.x, (-y) + self._parent.image.allocation.y) 
 
    # draw background for custom widget 
    ctx.paint() 
    ctx.restore() 
 
    # now draw what ever you want 
    self.rounded_rectangle(cr, 0, 0, width, height) 
    cr.set_line_width(1.0) 
    cr.set_source_color(gtk.gdk.color_parse('grey')) 
    cr.stroke_preserve() 
 
    gradient = cairo.LinearGradient(width/2, 0, width/2, height) 
    gradient.add_color_stop_rgba(0.00, 1, 1, 1, 0.9) 
    gradient.add_color_stop_rgba(1.00, 0.4, 0.4, 0.4, 0.5) 
    cr.set_source(gradient) 
    cr.fill()