Click-through tkinter windows
I have took the code of the linked question and made it work. See code below:
from tkinter import *from PIL import Image, ImageTkimport win32guiimport win32condef setClickthrough(hwnd): print("setting window properties") try: styles = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE) styles = win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, styles) win32gui.SetLayeredWindowAttributes(hwnd, 0, 255, win32con.LWA_ALPHA) except Exception as e: print(e)# Dimensionswidth = 1920 #self.winfo_screenwidth()height = 1080 #self.winfo_screenheight()root = Tk()root.geometry('%dx%d' % (width, height))root.title("Applepie")root.attributes('-transparentcolor', 'white', '-topmost', 1)root.config(bg='white') root.attributes("-alpha", 0.25)root.wm_attributes("-topmost", 1)bg = Canvas(root, width=width, height=height, bg='white')setClickthrough(bg.winfo_id())frame = ImageTk.PhotoImage(file="example.png")bg.create_image(1920/2, 1080/2, image=frame)bg.pack()root.mainloop()
The important difference between your try and the working example seems to be that there was in use the hwnd
of a canvas instead of a window.
I'm not abel to do exactly what you wish for but I have provided some code that outputs me this and hopefully sadisfy your needs. The extra code just removes the decoration (overrideredirect(1)
) and resizes the window to the img size, also it places it in the middle of the screen.:
from tkinter import *from PIL import Image, ImageTkimport win32guiimport win32condef setClickthrough(hwnd): print("setting window properties") try: styles = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE) styles = win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, styles) win32gui.SetLayeredWindowAttributes(hwnd, 0, 255, win32con.LWA_ALPHA) except Exception as e: print(e)def size_position_for_picture(): bbox = bg.bbox(img_id) w,h = bbox[2]-bbox[0],bbox[3]-bbox[1] x,y = sw/2-w/2,sh/2-h/2 root.geometry('%dx%d+%d+%d' % (w,h, x,y)) bg.configure(width=w,height=h) root = Tk()sw = root.winfo_screenwidth()sh = root.winfo_screenheight()root.overrideredirect(1)root.attributes("-alpha", 0.75)root.attributes('-transparentcolor', 'white', '-topmost', 1)bg = Canvas(root,bg='white',highlightthickness=0)root.config(bg='white')setClickthrough(bg.winfo_id())frame = ImageTk.PhotoImage(file="example.png")img_id = bg.create_image(0,0, image=frame,anchor='nw')bg.pack()size_position_for_picture()setClickthrough(bg.winfo_id())root.mainloop()
I have a function doing this for an application of mine as well, the code looks very similar to yours with some minor tweaks. You can try it out:
def set_clickthrough(hwnd, root): # Get window style and perform a 'bitwise or' operation to make the style layered and transparent, achieving # the clickthrough property l_ex_style = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE) l_ex_style |= win32con.WS_EX_TRANSPARENT | win32con.WS_EX_LAYERED win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, l_ex_style) # Set the window to be transparent and appear always on top win32gui.SetLayeredWindowAttributes(hwnd, win32api.RGB(0, 0, 0), 190, win32con.LWA_ALPHA) # transparent win32gui.SetWindowPos(hwnd, win32con.HWND_TOPMOST, root.winfo_x(), root.winfo_y(), 0, 0, 0)
And also, the following function to disable the clickthrough again
def disable_clickthrough(hwnd, root): # Calling the function again sets the extended style of the window to zero, reverting to a standard window win32api.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, 0) # Remove the always on top property again, in case always on top was set to false in options win32gui.SetWindowPos(hwnd, win32con.HWND_NOTOPMOST, root.winfo_x(), root.winfo_y(), 0, 0, 0)
You can get the window handle (hwnd
) by calling win32gui.FindWindow(None, root.title())
.