Is there a better way to make the fill of a polygon transparent, rather than using stipple? Heres an example:
import tkinter as tk
class GUI:
def __init__(self, master, x, y):
self.master = master
self.canvas = tk.Canvas(master, width=x, height=y)
self.canvas.pack()
self.canvas.create_polygon(10, 10, 10, 20, 200, 300, 250, 150, 10, 10,
outline="green", fill="blue")
self.canvas.create_polygon(100, 10, 10, 40, 50, 300, 250, 400, 100, 10,
outline="green", fill="red", stipple="gray50")
x, y = 500, 500
root = tk.Tk()
gui = GUI(root, x, y)
root.mainloop()
I would like to make the transparency of the red polygon realistic, like any software given the alpha parameter.
My solution is inspired by this answer on a similar question but for rectangles, not polygons.
Unfortunately, Tkinter doesn't support RGBA, so it's impossible just to pass fill args fill="#ff000055"
. Instead, we can create an image which contains the rectangle and has RGBA channel using PIL.
Here is an example:
from tkinter import *
from PIL import Image, ImageDraw, ImageTk
def create_polygon(*args, **kwargs):
if "alpha" in kwargs:
if "fill" in kwargs:
# Get and process the input data
fill = root.winfo_rgb(kwargs.pop("fill"))\
+ (int(kwargs.pop("alpha") * 255),)
outline = kwargs.pop("outline") if "outline" in kwargs else None
# We need to find a rectangle the polygon is inscribed in
# (max(args[::2]), max(args[1::2])) are x and y of the bottom right point of this rectangle
# and they also are the width and height of it respectively (the image will be inserted into
# (0, 0) coords for simplicity)
image = Image.new("RGBA", (max(args[::2]), max(args[1::2])))
ImageDraw.Draw(image).polygon(args, fill=fill, outline=outline)
images.append(ImageTk.PhotoImage(image)) # prevent the Image from being garbage-collected
return canvas.create_image(0, 0, image=images[-1], anchor="nw") # insert the Image to the 0, 0 coords
raise ValueError("fill color must be specified!")
return canvas.create_polygon(*args, **kwargs)
images = [] # to hold the newly created image(s)
root = Tk()
canvas = Canvas(width=260, height=310)
canvas.pack()
create_polygon(10, 10, 10, 20, 200, 300, 250, 150, 10, 10, fill="blue", alpha=0.5)
create_polygon(150, 100, 200, 120, 240, 180, 210, 200, 150, 150, 100, 200, fill="blue", alpha=0.2)
root.mainloop()