[英]Python tkinter canvas transparent
我希望使tkinter画布的背景透明,但仍具有画布的Mouse事件,这是我的代码,我在Windows 10和Python 3.6上:
from tkinter import *
import time
WIDTH = 500
HEIGHT = 500
LINEWIDTH = 1
TRANSCOLOUR = 'gray'
global old
old = ()
tk = Tk()
tk.title('Virtual whiteboard')
tk.wm_attributes('-transparentcolor', TRANSCOLOUR)
canvas = Canvas(tk, width=WIDTH, height=HEIGHT)
canvas.pack()
canvas.config(cursor='tcross')
canvas.create_rectangle(0, 0, WIDTH, HEIGHT, fill=TRANSCOLOUR, outline=TRANSCOLOUR)
def buttonmotion(evt):
global old
if old == ():
old = (evt.x, evt.y)
return
else:
canvas.create_line(old[0], old[1], evt.x, evt.y, width=LINEWIDTH)
old = (evt.x, evt.y)
def buttonclick(evt):
global old
canvas.create_line(evt.x-1, evt.y-1, evt.x, evt.y, width=LINEWIDTH)
old = (evt.x, evt.y)
canvas.bind('<Button-1>', buttonmotion)
canvas.bind('<B1-Motion>', buttonclick)
while True:
tk.update()
time.sleep(0.01)
运行代码时,它具有透明的背景,但是我选择了下面的内容,而不是画布。
我在win api的帮助下建立了一些解决方法,这是我的建议:
from tkinter import *
import time
import win32gui
import win32api
WIDTH = 500
HEIGHT = 500
LINEWIDTH = 1
TRANSCOLOUR = 'gray'
title = 'Virtual whiteboard'
global old
old = ()
global HWND_t
HWND_t = 0
tk = Tk()
tk.title(title)
tk.lift()
tk.wm_attributes("-topmost", True)
tk.wm_attributes("-transparentcolor", TRANSCOLOUR)
state_left = win32api.GetKeyState(0x01) # Left button down = 0 or 1. Button up = -127 or -128
canvas = Canvas(tk, width=WIDTH, height=HEIGHT)
canvas.pack()
canvas.config(cursor='tcross')
canvas.create_rectangle(0, 0, WIDTH, HEIGHT, fill=TRANSCOLOUR, outline=TRANSCOLOUR)
def putOnTop(event):
event.widget.unbind('<Visibility>')
event.widget.update()
event.widget.lift()
event.widget.bind('<Visibility>', putOnTop)
def drawline(data):
global old
if old !=():
canvas.create_line(old[0], old[1], data[0], data[1], width=LINEWIDTH)
old = (data[0], data[1])
def enumHandler(hwnd, lParam):
global HWND_t
if win32gui.IsWindowVisible(hwnd):
if title in win32gui.GetWindowText(hwnd):
HWND_t = hwnd
win32gui.EnumWindows(enumHandler, None)
tk.bind('<Visibility>', putOnTop)
tk.focus()
running = 1
while running == 1:
try:
tk.update()
time.sleep(0.01)
if HWND_t != 0:
windowborder = win32gui.GetWindowRect(HWND_t)
cur_pos = win32api.GetCursorPos()
state_left_new = win32api.GetKeyState(0x01)
if state_left_new != state_left:
if windowborder[0] < cur_pos[0] and windowborder[2] > cur_pos[0] and windowborder[1] < cur_pos[1] and windowborder[3] > cur_pos[1]:
drawline((cur_pos[0] - windowborder[0] - 5, cur_pos[1] - windowborder[1] - 30))
else:
old = ()
except Exception as e:
running = 0
print("error %r" % (e))
新代码位的快照说明:
tk.lift()
tk.wm_attributes("-topmost", True)
...
def putOnTop(event):
event.widget.unbind('<Visibility>')
event.widget.update()
event.widget.lift()
event.widget.bind('<Visibility>', putOnTop)
...
tk.bind('<Visibility>', putOnTop)
tk.focus()
这些行确保该窗口将始终位于所有其他窗口的顶部。
global HWND_t
HWND_t = 0
...
def enumHandler(hwnd, lParam):
global HWND_t
if win32gui.IsWindowVisible(hwnd):
if title in win32gui.GetWindowText(hwnd):
HWND_t = hwnd
win32gui.EnumWindows(enumHandler, None)
该代码位将通过当前显示的所有窗口,并抓住白板窗口的句柄(确保标题唯一,否则可能捕获错误的句柄)。
state_left = win32api.GetKeyState(0x01)
...
if HWND_t != 0:
windowborder = win32gui.GetWindowRect(HWND_t)
cur_pos = win32api.GetCursorPos()
state_left_new = win32api.GetKeyState(0x01)
if state_left_new != state_left:
if windowborder[0] < cur_pos[0] and windowborder[2] > cur_pos[0] and windowborder[1] < cur_pos[1] and windowborder[3] > cur_pos[1]:
drawline((cur_pos[0] - windowborder[0] - 5, cur_pos[1] - windowborder[1] - 30))
else:
old = ()
这个
如果一切正确,它将获取鼠标数据并绘制线条
当前模式是,在单击该按钮之前不绘制任何东西,然后在再次单击该按钮之前进行绘制。
我确定您已经想到了这一点,但是是否尝试将十六进制颜色设置为“”?
即
canvas = tk.Canvas(width, height, bg = "")
这适用于我的python版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.