24603

Python tkinter canvas transparent

Question:

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('<Button-1>', buttonmotion) canvas.bind('<B1-Motion>', 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.

Answer1:

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

Shot explanation of the new code bits:

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

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

<ol><li>Checks, if the handle is found</li> <li>Checks, if mouse button 1 is clicked or not</li> <li>Checks, if mouse is inside the window</li> </ol>

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.

Recommend

  • Why doesn't following the Fabric.IO steps for Twitter Login work for Android apps?
  • A question on capturing the button click event in ANOTHER mxml file
  • Make clear button backspace by one in python tkinter calculator
  • jquery-problem using val() in IE6
  • How to create JavaFX Transition with Equally-Timed Elements?
  • Writing a function to get all subsequences of size n in Haskell?
  • Shake recognition not working on iOS 4, does work on iOS 5
  • border-image-outset in CSS
  • Codemirror - minimum lines number
  • Compare Dictionary
  • Making a ball/circle move in cocoa using nsbezierpath(objective -c))?
  • Get VS to highlight all .Net 3.5 SP1 method calls
  • Omit template arguments when create an instance of template class from another instance of template
  • Can I create EventListener in AS3 from one Object and remove it from another Object?
  • View Controller Loads Twice - How Do I Fix It?
  • Tips for creating scalable WPF user control
  • How to set `secure` and `httpOnly` for Plones `__ac` cookie?
  • Cannot invoke my method on the array type int[]
  • Outlines on links in IE9 remains when focus is changed
  • Knockout custom binding handler
  • jQuery: add elements until a particular height is reached
  • Saving Changes After In-App Purchase Has Been Purchased
  • Android fill_parent issue
  • Retrieving value from sql ExecuteScalar()
  • jQuery show() function is not executed in Safari if submit handler returns true
  • How to convert from System.Drawing.Color to Excel.ColorFormat in C#? Change comment color
  • jquery mobile loadPage not working
  • Properly structure and highlight a GtkPopoverMenu using PyGObject
  • Matrix multiplication with MKL
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • How to get Windows thread pool to call class member function?
  • Is there any way to bind data to data.frame by some index?
  • Easiest way to encapsulate a HTML5 webpage into an android app?
  • Busy indicator not showing up in wpf window [duplicate]
  • costura.fody for a dll that references another dll
  • Observable and ngFor in Angular 2
  • How to Embed XSL into XML
  • UserPrincipal.Current returns apppool on IIS
  • Conditional In-Line CSS for IE and Others?
  • java string with new operator and a literal