Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带有透明图像的可拖动Tkinter标签仍然覆盖来自父画布的图像_Python_Tkinter_Tkinter Canvas - Fatal编程技术网

Python 带有透明图像的可拖动Tkinter标签仍然覆盖来自父画布的图像

Python 带有透明图像的可拖动Tkinter标签仍然覆盖来自父画布的图像,python,tkinter,tkinter-canvas,Python,Tkinter,Tkinter Canvas,我正致力于在背景图像上添加可拖动标签,其中标签是具有透明背景的图像。用于标签本身的图像是透明的,但标签本身相对于其父画布是不透明的。由于标签是可拖动的,我不能轻松地使用父图像作为标签,并将透明图像粘贴在顶部 dragon是一个可拖动的标签,具有透明的背景,但您可以看到标签本身不是透明的,并且覆盖了画布图像 龙图像本身有一个透明的背景,因为正常的背景是蓝色的,所以我知道问题在于标签的透明度 理想的行为是允许标签是透明的,因此当标签上的图像是透明的时,标签应该显示到下面的图像 下面是一个简单的例子

我正致力于在背景图像上添加可拖动标签,其中标签是具有透明背景的图像。用于标签本身的图像是透明的,但标签本身相对于其父画布是不透明的。由于标签是可拖动的,我不能轻松地使用父图像作为标签,并将透明图像粘贴在顶部

dragon是一个可拖动的标签,具有透明的背景,但您可以看到标签本身不是透明的,并且覆盖了画布图像

龙图像本身有一个透明的背景,因为正常的背景是蓝色的,所以我知道问题在于标签的透明度

理想的行为是允许标签是透明的,因此当标签上的图像是透明的时,标签应该显示到下面的图像

下面是一个简单的例子:

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()
我想看到的是一个蓝色的正方形,红色背景,没有边框。但在上面的示例中,显示灰色边框,因为它是通过透明图像看到的标签;调整窗口大小时很容易看到这一点。我怀疑如果标签是透明的,这将解决我的问题


任何帮助都会很好,谢谢

如果要将部分透明的图像(如龙)拖到背景图像上,可以使用
画布

其思想不是使用标签,而是使用
Canvas
create\u image
方法。 首先,用
画布显示背景图像。创建图像(0,0,image=background\u image,anchor='nw')
,然后用标记'draggable'显示所有可拖动图像:
画布。创建图像(x,y,image=draggable\u 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()
将tkinter作为tk导入
将numpy作为np导入
从PIL导入图像,ImageTk
#拖动回调
拖动的项目=无
当前坐标=0,0
def开始拖动(事件):
全球电流坐标
全局拖拽项
结果=canvas.find_with tag('current'))
如果结果为:
拖动的项目=结果[0]
当前坐标=canvas.canvasx(event.x),canvas.canvasy(event.y)
其他:
拖动的项目=无
def停止拖动(事件):
拖动的项目=无
def拖动(事件):
全球电流坐标
xc,yc=canvas.canvasx(event.x),canvas.canvasy(event.y)
dx,dy=xc-当前坐标[0],yc-当前坐标[1]
当前坐标=xc,yc
canvas.move(拖动的项目,dx,dy)
#创作图片
蓝色方形透明边框=[[0,0,0,0]]*100]*10+[[0,0,0,0]]*30+[[0,0255255]]*40+[[0,0,0,0]]*30]*40+[[0,0,0,0]]*100]*10
blue\u square\u transparent\u border=np.数组(blue\u square\u transparent\u border,dtype='uint8')
pil\u image=image.fromarray(蓝色方形透明边框)
背景数据=np.0((200400,4))
背景数据[:,:,0]=255*np.one((200400))
背景数据[:,:,3]=255*np.one((200400))
background\u data=np.array(background\u data,dtype='uint8')
pil\u image\u bg=image.fromarray(背景数据)
#创建GUI
root=tk.tk()
背景图像=图像k.PhotoImage(pil\u图像bg)
tk_图像=图像tk.照片图像(pil_图像)
canvas=tk.canvas(根,宽度=400,高度=200)
canvas.pack()
#将“可拖动”标记绑定到鼠标事件
canvas.tag\u bind('draggable','',start\u drag)
canvas.tag\u bind('draggable','',stop\u drag)
canvas.tag_bind('draggable','',drag)
#展示图片
canvas.create_image(0,0,image=background_image,anchor='nw')
canvas.create_image(0,0,image=tk_image,anchor='nw',tag='draggable')
root.mainloop()

我想这可能会有帮助@Nae首先为这个糟糕的问题感到抱歉!我用一个简单的例子更新了信息。我也看了你的链接,但我不认为它解决了我的问题!请让我知道,如果你有任何更多的投入!所有小部件都有背景色,不能将其设置为透明。您只能使用
create_image
在widget上放置透明图像。感谢@furas提供的信息,恐怕这就是答案。那么,有没有办法制作一个非矩形的小部件呢?谢谢!我确实意识到你可以在画布上画两个图像,并将它们作为单独的图像进行维护。我以为一个会覆盖另一个。这是一个更简单的解决方案!