Click-through tkinter windows Click-through tkinter windows tkinter tkinter

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.:

enter image description here

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