Python tkinter canvas transparente

Estoy buscando hacer que el fondo del canvas de tkinter sea transparente, pero todavía tengo eventos del canvas del mouse, aquí está mi código, estoy en 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) 

Cuando ejecuto el código, crea un fondo transparente, pero selecciono las cosas debajo, en lugar del canvas.

Construyo una pequeña solución con la ayuda de la API de victoria, aquí está mi sugerencia:

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

Explicación del disparo de los nuevos bits de código:

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

Estas líneas aseguran que la ventana siempre estará encima de todas las demás ventanas.

 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) 

Este bit de código irá a través de todas las ventanas que se muestran actualmente y captura el controlador de la ventana de la pizarra (asegúrese de que el título sea único, o esto podría capturar el controlador incorrecto).

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

Esta

  1. Comprobaciones, si se encuentra el mango.
  2. Comprobaciones, si se hace clic o no en el botón 1 del mouse
  3. Comprobaciones, si el ratón está dentro de la ventana.

Si todo es cierto, toma los datos del mouse y dibuja la línea.

el modo actual es que no dibuja nada hasta que se hace clic en el botón y luego se dibuja hasta que se vuelve a hacer clic en el botón.

Estoy seguro de que has pensado en esto, pero ¿has intentado configurar el color hexadecimal como “”?

es decir

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

Eso funciona para mi versión de python.