python tkinter画布,Python Tkinter画布透明

I am looking to make the background of the tkinter canvas transparent, but still have Mouse events of the canvas, here is my code, I am on 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('', buttonmotion)

canvas.bind('', buttonclick)

while True:

tk.update()

time.sleep(0.01)

When run the code, it makes a transparent background, but I select the things under, instead of the canvas.

解决方案

I build a little workaround with the help of the win api, here is my suggestion:

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('')

event.widget.update()

event.widget.lift()

event.widget.bind('', 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('', 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))

Shot explanation of the new code bits:

tk.lift()

tk.wm_attributes("-topmost", True)

...

def putOnTop(event):

event.widget.unbind('')

event.widget.update()

event.widget.lift()

event.widget.bind('', putOnTop)

...

tk.bind('', putOnTop)

tk.focus()

These lines ensure, that the window will be always be on top of all other windows.

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)

This code bit will go through all the windows currently displayed and catches the handle of the whiteboard window (make sure the title is unique, or this could capture the wrong handle).

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 = ()

This

Checks, if the handle is found

Checks, if mouse button 1 is clicked or not

Checks, if mouse is inside the window

if all is true, it takes the mouse data and draws the line

the current mode is, that it doesn't draw anything till the button is clicked and then draws until the button is clicked again.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值