Home > Back-end >  How to detect if a window is in front of other windows
How to detect if a window is in front of other windows

Time:10-09

Is there a way to bring a child window in front when the parent is focused? What I am trying to resolve is this: I have a parent window (root) and a child window (TopLevel) called "menu." The child window is a floating menu with several buttons on it and is titlebar-less.

If I set menu.wm_attributes('-topmost', 1) than the child window called "menu" stays on top all the times, even if I open another app the menu stays above all windows, which is not very practical.

If I reset menu.wm_attributes('-topmost', 0) and that I focus on the parent window, the child window stays behind all other windows, and I cannot see it. This occurs if I am running my app and then have to open another app such as Dbeaver or Firefox. I then bring my app to the front but the child stays behind Dbeaver or Firefox.

What I am trying to do is detect when the main window is focused so that I can then bring the child window in the front so that both the root and the toplevel are in the front.

I did some extensive search on the net. Found a lot about detecting if the window is open or closed but nothing about detecting if the windows is open.

I use python 3.8 and tkinter.

Here is what I have so far in that section of the code. Doesn't work perfectly yet but it is very close:

def push_menu_front(event):
    focus = 0
    focus  = 1
    if focus != 0:
        print("focus is 1")
        menu.wm_attributes('-topmost', 1)


def push_menu_back(event):
    focus = 0
    focus  = 1
    if focus != 0:
        print("focus is 0")
        menu.wm_attributes('-topmost', 0)


root.bind("<FocusIn>", bring_menu_front)
root.bind("<FocusOut>", bring_menu_back)

CodePudding user response:

So the solution is pretty interesting:

from tkinter import Tk, Toplevel


def focus_in(event=None):
    top.attributes('-topmost', True)
    top.attributes('-topmost', False)


root = Tk()
root.title('master')
root.bind('<FocusIn>', focus_in)

top = Toplevel(root)
top.title('top')

root.mainloop()

Now whenever you open the main window the menu also comes to the front and if you focus out then both disappear because focus goes to the other window.

CodePudding user response:

With Matiiss' suggestions, I got the following code to work for me. Note that it works like a charm on Linux. On Windows, it acts differently. I haven't resolved this yet. On Windows you have to minimize the main window to have both parent and child go in the background.

from tkinter import Tk, Toplevel


def focus_in(event=None):
    top.attributes('-topmost', True)

def focus_out(event=None):
    top.attributes('-topmost', False)


root = Tk()
root.title('master')
root.geometry("300x300 300 100")
root.bind('<FocusIn>', focus_in)
root.bind('<FocusOut>', focus_out)

top = Toplevel(root)
top.title('top')
top.geometry("120x300 610 100")

root.mainloop()
  • Related