繁体   English   中英

Python Tkinter画布透明

[英]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 = ()

这个

  1. 检查是否找到了句柄
  2. 检查是否单击了鼠标按钮1
  3. 检查鼠标是否在窗口内

如果一切正确,它将获取鼠标数据并绘制线条

当前模式是,在单击该按钮之前不绘制任何东西,然后在再次单击该按钮之前进行绘制。

我确定您已经想到了这一点,但是是否尝试将十六进制颜色设置为“”?

canvas = tk.Canvas(width, height, bg = "")

这适用于我的python版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM