具有透明图像的可拖动 Tkinter 标签仍然覆盖来自父级的图像 Canvas
Draggable Tkinter Label With Transparent Image Still Covers Image from Parent Canvas
我正在努力在背景图像上添加可拖动标签,其中标签是具有透明背景的图像。用于标签本身的图像是透明的,但标签本身相对于其父级 canvas 不是透明的。由于标签是可拖动的,我不能轻易地使用父图像作为标签,并将透明图像粘贴在上面。
龙是一个可拖动的标签,背景是透明的,但是你看标签本身是不透明的,它覆盖了canvas图像。
龙的图像本身有透明背景,因为正常背景是蓝色的,所以我知道问题出在标签透明度上。
所需的行为是允许标签透明,因此当标签上的图像透明时,标签应显示到下面的图像。
这是一个最小的例子:
from PIL import Image, ImageTk
import numpy as np
import tkinter as tk
#Creates a blue square with a transparent border
blue_square_transparent_border = [[[0,0,0,0]]*100]*10 + [[[0,0,0,0]]*30 + [[0,0,255,255]]*40 + [[0,0,0,0]]*30]*40 + [[[0,0,0,0]]*100]*10
blue_square_transparent_border = np.array(blue_square_transparent_border, dtype='uint8')
#convert numpy array to PIL image
pil_image = Image.fromarray(blue_square_transparent_border)
root = tk.Tk()
root.configure(background='red')
#convert PIL image to tkinter image
tk_image = ImageTk.PhotoImage(pil_image)
#create label
image_label = tk.Label(root, image=tk_image)
image_label.pack()
root.mainloop()
我想看到的是一个蓝色正方形,红色背景,没有边框。但在上面的示例中,出现了灰色边框,因为它是通过透明图像看到的标签;当您调整 window 的大小时很容易看到这一点。我怀疑如果标签是透明的,这将解决我的问题。
任何帮助都会很棒,谢谢!
如果您想将部分透明的图像(如龙)拖到背景图像上,您可以使用 Canvas
:
思路不是用标签,而是Canvas
的create_image
方法。
首先,使用 canvas.create_image(0, 0, image=background_image, anchor='nw')
显示您的背景图片,然后使用标签 'draggable': canvas.create_image(x, y, image=draggable_image, anchor='nw', tag='draggable')
显示所有可拖动的图像。最后将标签'draggable'绑定到鼠标事件
这是一个例子:
import tkinter as tk
import numpy as np
from PIL import Image, ImageTk
# drag callbacks
dragged_item = None
current_coords = 0, 0
def start_drag(event):
global current_coords
global dragged_item
result = canvas.find_withtag('current')
if result:
dragged_item = result[0]
current_coords = canvas.canvasx(event.x), canvas.canvasy(event.y)
else:
dragged_item = None
def stop_drag(event):
dragged_item = None
def drag(event):
global current_coords
xc, yc = canvas.canvasx(event.x), canvas.canvasy(event.y)
dx, dy = xc - current_coords[0], yc - current_coords[1]
current_coords = xc, yc
canvas.move(dragged_item, dx, dy)
#Create pictures
blue_square_transparent_border = [[[0,0,0,0]]*100]*10 + [[[0,0,0,0]]*30 + [[0,0,255,255]]*40 + [[0,0,0,0]]*30]*40 + [[[0,0,0,0]]*100]*10
blue_square_transparent_border = np.array(blue_square_transparent_border, dtype='uint8')
pil_image = Image.fromarray(blue_square_transparent_border)
background_data = np.zeros((200, 400, 4))
background_data[:, :, 0] = 255 * np.ones((200, 400))
background_data[:, :, 3] = 255 * np.ones((200, 400))
background_data = np.array(background_data, dtype='uint8')
pil_image_bg = Image.fromarray(background_data)
# create GUI
root = tk.Tk()
background_image = ImageTk.PhotoImage(pil_image_bg)
tk_image = ImageTk.PhotoImage(pil_image)
canvas = tk.Canvas(root, width=400, height=200)
canvas.pack()
# bind 'draggable' tag to mouse events
canvas.tag_bind('draggable', '<ButtonPress-1>', start_drag)
canvas.tag_bind('draggable', '<ButtonRelease-1>', stop_drag)
canvas.tag_bind('draggable', '<B1-Motion>', drag)
# display pictures
canvas.create_image(0, 0, image=background_image, anchor='nw')
canvas.create_image(0, 0, image=tk_image, anchor='nw', tag='draggable')
root.mainloop()
我正在努力在背景图像上添加可拖动标签,其中标签是具有透明背景的图像。用于标签本身的图像是透明的,但标签本身相对于其父级 canvas 不是透明的。由于标签是可拖动的,我不能轻易地使用父图像作为标签,并将透明图像粘贴在上面。
龙是一个可拖动的标签,背景是透明的,但是你看标签本身是不透明的,它覆盖了canvas图像。
龙的图像本身有透明背景,因为正常背景是蓝色的,所以我知道问题出在标签透明度上。
所需的行为是允许标签透明,因此当标签上的图像透明时,标签应显示到下面的图像。
这是一个最小的例子:
from PIL import Image, ImageTk
import numpy as np
import tkinter as tk
#Creates a blue square with a transparent border
blue_square_transparent_border = [[[0,0,0,0]]*100]*10 + [[[0,0,0,0]]*30 + [[0,0,255,255]]*40 + [[0,0,0,0]]*30]*40 + [[[0,0,0,0]]*100]*10
blue_square_transparent_border = np.array(blue_square_transparent_border, dtype='uint8')
#convert numpy array to PIL image
pil_image = Image.fromarray(blue_square_transparent_border)
root = tk.Tk()
root.configure(background='red')
#convert PIL image to tkinter image
tk_image = ImageTk.PhotoImage(pil_image)
#create label
image_label = tk.Label(root, image=tk_image)
image_label.pack()
root.mainloop()
我想看到的是一个蓝色正方形,红色背景,没有边框。但在上面的示例中,出现了灰色边框,因为它是通过透明图像看到的标签;当您调整 window 的大小时很容易看到这一点。我怀疑如果标签是透明的,这将解决我的问题。
任何帮助都会很棒,谢谢!
如果您想将部分透明的图像(如龙)拖到背景图像上,您可以使用 Canvas
:
思路不是用标签,而是Canvas
的create_image
方法。
首先,使用 canvas.create_image(0, 0, image=background_image, anchor='nw')
显示您的背景图片,然后使用标签 'draggable': canvas.create_image(x, y, image=draggable_image, anchor='nw', tag='draggable')
显示所有可拖动的图像。最后将标签'draggable'绑定到鼠标事件
这是一个例子:
import tkinter as tk
import numpy as np
from PIL import Image, ImageTk
# drag callbacks
dragged_item = None
current_coords = 0, 0
def start_drag(event):
global current_coords
global dragged_item
result = canvas.find_withtag('current')
if result:
dragged_item = result[0]
current_coords = canvas.canvasx(event.x), canvas.canvasy(event.y)
else:
dragged_item = None
def stop_drag(event):
dragged_item = None
def drag(event):
global current_coords
xc, yc = canvas.canvasx(event.x), canvas.canvasy(event.y)
dx, dy = xc - current_coords[0], yc - current_coords[1]
current_coords = xc, yc
canvas.move(dragged_item, dx, dy)
#Create pictures
blue_square_transparent_border = [[[0,0,0,0]]*100]*10 + [[[0,0,0,0]]*30 + [[0,0,255,255]]*40 + [[0,0,0,0]]*30]*40 + [[[0,0,0,0]]*100]*10
blue_square_transparent_border = np.array(blue_square_transparent_border, dtype='uint8')
pil_image = Image.fromarray(blue_square_transparent_border)
background_data = np.zeros((200, 400, 4))
background_data[:, :, 0] = 255 * np.ones((200, 400))
background_data[:, :, 3] = 255 * np.ones((200, 400))
background_data = np.array(background_data, dtype='uint8')
pil_image_bg = Image.fromarray(background_data)
# create GUI
root = tk.Tk()
background_image = ImageTk.PhotoImage(pil_image_bg)
tk_image = ImageTk.PhotoImage(pil_image)
canvas = tk.Canvas(root, width=400, height=200)
canvas.pack()
# bind 'draggable' tag to mouse events
canvas.tag_bind('draggable', '<ButtonPress-1>', start_drag)
canvas.tag_bind('draggable', '<ButtonRelease-1>', stop_drag)
canvas.tag_bind('draggable', '<B1-Motion>', drag)
# display pictures
canvas.create_image(0, 0, image=background_image, anchor='nw')
canvas.create_image(0, 0, image=tk_image, anchor='nw', tag='draggable')
root.mainloop()