Tying to set non-interactable (click-through) overlay with TkInter

Viewed 1133

I've gone through several other posts regarding similar issues and all seem to point to this code. Since, I'm working on creating a desktop overlay, I setup a short program to create a top window and hopefully isolate the issue but, despite my efforts I can't figure out why this seemingly widely accepted solution is failing for me or what I could be missing.

I've verified that the handle being retrieved is referencing the correct window, trimmed away unnecessary functions, and explored other variations of setting window styles through personal trial and error and mimicking some examples found through programcreek.com.

from tkinter import *
from PIL import Image, ImageTk
from win32gui import GetForegroundWindow, ShowWindow, FindWindow,
                     SetWindowLong, GetWindowLong
from win32con import SW_MINIMIZE, WS_EX_LAYERED, WS_EX_TRANSPARENT, GWL_EXSTYLE

def setClickthrough(root, window="Applepie"):
    hwnd = FindWindow(None, window)
    styles = GetWindowLong(hwnd, GWL_EXSTYLE)
    styles |= WS_EX_LAYERED | WS_EX_TRANSPARENT
    print(SetWindowLong(hwnd, GWL_EXSTYLE, styles))

# Dimensions
width = 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)
root.bg = Canvas(root, width=width, height=height, bg='white')

setClickthrough(root)

frame = ImageTk.PhotoImage(file="Resources/Test/Test-0000.gif")
root.bg.create_image(1920/2, 1080/2, image=frame)
root.bg.pack()
root.mainloop()

The TkInter window was successfully made transparent and clickable-through using the solution provided by acw1668 using:

root.attributes('-transparentcolor', 'white', '-topmost', 1)
root.config(bg='white')
root.bg = Canvas(root, width=width, height=height, bg='white')

Problem persists with creating an image in the canvas. Need to be able to have additional images be clickable through as well:

frame = ImageTk.PhotoImage(file="Resources/Test/Test-0000.gif")
root.bg.create_image(1920/2, 1080/2, image=frame)
1 Answers

Turns out the handle was not being captured properly using FindWindow and using alternatives such as root.frame() or root.winfo_id() did not match the handle of the window for some reason. By passing in the winfo_id() of the Canvas, I was able to get the below code to work:

    self.root.config(bg='#000000') 
    self.root.wm_attributes("-topmost", 1)
    self.root.attributes('-transparentcolor', '#000000', '-topmost', 1)

    print("Configuring bg")
    self.bg = Canvas(self.root, highlightthickness=0)
    self.setClickthrough(self.bg.winfo_id())

Calling:

def setClickthrough(self, hwnd):
    print("setting window properties")
    try:
        styles = GetWindowLong(hwnd, GWL_EXSTYLE)
        styles = WS_EX_LAYERED | WS_EX_TRANSPARENT
        SetWindowLong(hwnd, GWL_EXSTYLE, styles)
        SetLayeredWindowAttributes(hwnd, 0, 255, LWA_ALPHA)
    except Exception as e:
        print(e)
Related