0

I'm using Tkinter to create an overlay on top of every other windows. For now, if I click on my overlay, like an image or a button, it changes the active windows to Tkinter, obviously. What i want is to use my overlay but keeping my active windows. I looked around click-through type of things but for now it's either i can't click my buttons and the window remain active, either I can but Tkinter switch to active window. I'm new to python and I'm not sure if my code worth sharing, as it is quite simple, but it might to avoid any misunderstanding :

root = Tk()
root.geometry("1920x1080")
root.config(bg='#add123')
root.wm_attributes('-transparentcolor', '#add123')
root.attributes("-fullscreen", True)
root.attributes('-topmost',True)

EDIT: I'm going to try to be as clear as possible. If I use a GUI made with Tkinter, like any others widows, it will become the "Active window". So if I'm using my overlay with another app let's say Firefox. Thanks to topmost attribute, my overlay will stay on top while using Firefox as "active window" which is what i want. But if click a button on my overlay, the "active window" will become Tkinter. To give an example, if I star typing in the URL bar then click a button on my overlay, I won't be able to continue to type in the URL bar since Firefox is no more the "Active window". This is an issue to me as I'm using this overlay over a full screen app that pause when it's inactive. Thanks again ;)

EDIT2: So I might be doing something wrong i'll share the code with you:

from tkinter import *
from PIL import Image, ImageTk
import win32gui
import win32con

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

width = 1920 #self.winfo_screenwidth()
height = 1080 #self.winfo_screenheight()

root = Tk()
root.geometry("1920x1080")
root.config(bg='#add123')
root.wm_attributes('-transparentcolor', '#add123')
root.attributes("-fullscreen", True)
root.wm_attributes("-topmost", 1)
bg = Canvas(root, width=width, height=height)

setClickthrough(bg.winfo_id())

frame = ImageTk.PhotoImage(file="sample.png")
bg.create_image(1920/2, 1080/2, image=frame)
bg.button_1 = Button(root,text='Click')
bg.button_1.pack()
bg.pack()
root.mainloop()

At this point, the image "sample.png" is clickable trough but not the Button. If that make sense

  • Nope, this is just not how user interfaces work. The top window is the one that receives UI messages. If you are trying to track mouse motion and button clicks, you can do that through hooks, but not by using a transparent window. – Tim Roberts Apr 23 '23 at 19:38
  • tkinter provides a built in mechanic for this, it is called `grab_set`, it is a non trivial and non intuitive technique you are interested in and for most cases it isn't necessary. What is your overall goal, you might doing things more complicated than they need to be. – Thingamabobs Apr 23 '23 at 19:40
  • @Thingamabobs: I think the OP wants the opposite of a grab - they want the tkinter app to never get focus rather than to steal the focus. – Bryan Oakley Apr 23 '23 at 19:42
  • @TimRoberts that's simply not true, you can do work around a heavy hook. – Thingamabobs Apr 23 '23 at 19:42
  • @BryanOakley as I understand, they want an overlay window. Most likely to make some sort of *shiny buttons* or a *glass effect* and if I recall correctly one could redirect the events to the window underneath. – Thingamabobs Apr 23 '23 at 19:46
  • @Thingamabobs, not really. The idea is too have an overlay, with very much clickable button, but weither i click is or not my active windows remain the one i'm using under my overlay. I tough i was not worth mentionning, but i'm rebuilding a project that i made in Auto Hotkey in python. The attribute that does very much what i needed in AHK was the following: 'Gui +E0x08000000' if you guys want to google it to see what it's doing on a GUI in AHK script – Edgar Salvador De Carvalho Apr 23 '23 at 19:52
  • Is your *active window* also a window built with tkinter or not ? If not, tkinter does not support it, but you could handle it via the window manager. At least for windows I have made it work in the past in this [Q&A](https://stackoverflow.com/a/67545792/13629335) – Thingamabobs Apr 23 '23 at 19:57
  • @Thingamabobs, yup, that the very topic i was thinking when i mentionned click trough solution. It tryed again, differently. It work fine for click trough non interactive content like but deffinitly not working with button,. I was expecting that Tkinter was not the good option. Any suggestion for an overlay of that type in python? I'd love to avoid to go to C++ – Edgar Salvador De Carvalho Apr 23 '23 at 20:28
  • I still don't get what you want, please go ahead and [edit] your question with all the details needed. – Thingamabobs Apr 23 '23 at 20:34
  • I just did ;) thanks for your patience – Edgar Salvador De Carvalho Apr 23 '23 at 21:38
  • So you need just a partial-clicktrhough-area? Again you would need to use the window manager for this task, something like in the Q&A I just posted. Try making this canvas to your area and position your buttons around it. Could work, but not sure, since I never tried. – Thingamabobs Apr 23 '23 at 21:46

1 Answers1

0

You need just a partial-clicktrhough-area?

Like I had explained in the comment section. You would need to use the window manager of your operating system for this task.

Don't try to send events to other application, you might break something and that's why it's considered an anti pattern (something to avoid).

Something like in the Q&A I just posted will use native calls. Try making this canvas to your area and position your buttons around it. It Could work, but not sure, since I never tried.

Alternatively try to reverse the click through attribute when your pointer moves in the area of your interactive section.

Also note that, at least under Windows, you will always lose the focus on the previous window when interacting with another and this seems not avoidable, since the caret (the blinking thingy where you type at) is related to this.

Thingamabobs
  • 7,274
  • 5
  • 21
  • 54