2017-03-18 114 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

謝謝,我使用了一個稍微更基本的版本,但使用相同的代碼 –