如何使 tkinter canvas 背景透明?

How to make a tkinter canvas background transparent?

我正在制作一个国际象棋程序,我希望能够拖动棋子。为此,我将作品的图像放在 Canvas 上,以便可以拖动(如果需要,我也可以使用 Label)。但是,当我拖动作品时,作品的图像周围出现了一个白色方块。

我研究这个问题的时候,很多人给出了这样的解决方案:

drag_canvas = Canvas(self, height=80, width=80, bg="yellow")
root.wm_attributes("-transparentcolor", "yellow")

这导致背景透明但不是棋盘可见,而是GUI背后的程序

.

有什么方法可以让背景透明并显示后面的棋盘而不是 tkinter 后面的程序window?

注意:我不介意使用任何其他小部件(例如 Label),但它们必须使用默认带有 Python 的模块(因此没有 PIL),因为需要使用此程序在无法下载其他模块的环境中。

Question: How to make a tkinter canvas background transparent?

唯一可能的config(...选项,将背景设置为空

c.config(bg='')

results with: _tkinter.TclError: unknown color name ""


得到这个结果:

你必须把棋盘和棋子放在同一个.Canvas(...

    self.canvas = Canvas(self, width=500, height=200, bd=0, highlightthickness=0)
    self.canvas.create_rectangle(245,50,345,150, fill='white')

    self.image = tk.PhotoImage(file='chess.png')
    self.image_id = self.canvas.create_image(50,50, image=self.image)

    self.canvas.move(self.image_id, 245, 100)

测试 Python: 3.5 - TkVersion: 8.6

一个windows唯一的解决方案是使用可以安装的pywin32模块:

pip install pywin32

使用 pywin32,您可以更改 window exstyle 并将 canvas 设置为分层 window。分层 window 可以有一个透明的色键,并在下面的示例中完成:

import tkinter as tk
import win32gui
import win32con
import win32api
        

root = tk.Tk()
root.configure(bg='yellow')
canvas = tk.Canvas(root,bg='#000000')#full black
hwnd = canvas.winfo_id()
colorkey = win32api.RGB(0,0,0) #full black in COLORREF structure
wnd_exstyle = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
new_exstyle = wnd_exstyle | win32con.WS_EX_LAYERED
win32gui.SetWindowLong(hwnd,win32con.GWL_EXSTYLE,new_exstyle)
win32gui.SetLayeredWindowAttributes(hwnd,colorkey,255,win32con.LWA_COLORKEY)
canvas.create_rectangle(50,50,100,100,fill='blue')
canvas.pack()

解释:

首先我们需要 handle of the window which is called hwnd and we can get it in tkinter by .winfo_id().

接下来我们得到实际的 extended window style by GetWindowLong 并使用 win32con.GWL_EXSTYLE 询问具体的扩展样式信息。

之后我们在十六进制中进行按位运算以改变 wnd_exstyle | win32con.WS_EX_LAYERED 的样式,结果是我们的 new_style.

现在我们可以将扩展样式设置为 window 和 SetWindowLong. Finally we have our LayeredWindow which has additional Attributes we can work with. A transparent ColorKey can be set with SetLayeredWindowAttributes 而我们只是使用 LWA_COLORKEY alpha 参数对我们没有用。

重要说明:定义透明色键后,canvas中具有该颜色的所有内容都将是透明的。