设置 tkinter canvas 的图形的透明度

参考资料:How to make a tkinter canvas rectangle transparent?

本文以 矩形 为例说明。

方法1:使用 位图填充

from tkinter import Tk, Canvas

root = Tk()
root.geometry("400x400+100+100")  # WIDTHxHEIGHT+X+Y
canvas = Canvas(root)
canvas.create_rectangle(20, 50, 200, 300, outline="black",
                       width=2, fill='red')
canvas.create_rectangle(30, 60, 300, 100, outline="black",
                       width=2, activefill='skyblue',  activestipple="gray50")
canvas.pack(fill='both', expand=1)
root.mainloop()

效果图:

图1 位图填充实现图形透明度

可以看出,效果有那么个意思了,但是,设置透明度并不方便。

方法2 借助 PIL 设置

from tkinter import Tk, Canvas
from PIL import Image, ImageTk

images = []  # to hold the newly created image


def create_rectangle(x1, y1, x2, y2, **kwargs):
    if 'alpha' in kwargs:
        alpha = int(kwargs.pop('alpha') * 255)
        fill = kwargs.pop('fill')
        fill = root.winfo_rgb(fill) + (alpha,)
        image = Image.new('RGBA', (x2-x1, y2-y1), fill)
        images.append(ImageTk.PhotoImage(image))
        canvas.create_image(x1, y1, image=images[-1], anchor='nw')
    canvas.create_rectangle(x1, y1, x2, y2, **kwargs)


root = Tk()
root.geometry("400x400+100+100")  # WIDTHxHEIGHT+X+Y
canvas = Canvas(root)

create_rectangle(10, 10, 200, 100, fill='blue')
create_rectangle(50, 50, 250, 150, fill='green', alpha=.5)
create_rectangle(80, 80, 150, 120, fill='skyblue', alpha=.8)
canvas.pack(fill='both', expand=1)
root.mainloop()

效果如下:

图2 实现真正意义上的透明度设置

也可以改写为类的形式:

from tkinter import Tk, Canvas
from PIL import Image, ImageTk

class Graph(Canvas):
    '''Graphic elements are composed of line(segment), rectangle, ellipse, and arc.
    '''

    def __init__(self, master=None, cnf={}, **kw):
        '''The base class of all graphics frames.

        :param master: a widget of tkinter or tkinter.ttk.
        '''
        super().__init__(master, cnf, **kw)
        self.rectangle_selector = []
        self.tag_bind('current', "<ButtonPress-1>", self.scroll_start)
        self.tag_bind('current', "<B1-Motion>", self.scroll_move)
        
    def scroll_start(self, event):
        self.scan_mark(event.x, event.y)

    def scroll_move(self, event):
        self.scan_dragto(event.x, event.y, gain=1)
        
    def create_mask(self, size, alpha, fill):
        '''设置透明蒙版'''
        fill = self.master.winfo_rgb(fill) + (alpha,)
        image = Image.new('RGBA', size, fill)
        return image
        
    def draw_rectangle(self, x1, y1, x2, y2, **kw):
        if 'alpha' in kw:
            size = x2-x1, y2-y1
            alpha = int(kw.pop('alpha') * 255)
            fill = kw.pop('fill')
            image = self.create_mask(size, alpha, fill)
            self.rectangle_selector.append(ImageTk.PhotoImage(image))
            self.create_image(x1, y1, image=self.rectangle_selector[-1], anchor='nw', tags='mask')
        return self.create_rectangle(x1, y1, x2, y2, **kw)
        
        
root = Tk()
root.geometry("400x400+100+100")  # WIDTHxHEIGHT+X+Y
self = Graph(root)

self.draw_rectangle(10, 10, 200, 100, fill='blue')
self.draw_rectangle(50, 50, 250, 150, fill='green', alpha=.5, tags='selected')
self.draw_rectangle(80, 80, 150, 120, fill='yellow', alpha=.8)
self.pack(fill='both', expand=1)
root.mainloop()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。