2017-03-18 108 views
1

我期待让Tkinter的画布的背景透明,但仍然有画布的鼠标事件,这里是我的代码,我在Windows 10,Python的3.6:Python的Tkinter的帆布透明

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) 

运行代码时,它会创建一个透明背景,但我选择下面的东西,而不是画布。

+0

该程序的期望行为究竟是什么? – Alex

+0

一个虚拟白板,所以你可以在桌面上叠加线条,文本等 –

+0

相关http://stackoverflow.com/q/19080499/4489998 – TrakJohnson

回答

1

我建立同赢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. 检查,如果鼠标在窗口
内部

如果全部为真,则需要鼠标数据并绘制线

当前模式是,它不会绘制任何东西,直到点击按钮,然后绘制直到再次单击该按钮。

+1

谢谢,我使用了一个稍微更基本的版本,但使用相同的代码 –