Home>
I want to achieve

When you press a button in a window while running Python, one pop-up window is brought to the foreground.
Makes the back window inoperable while the pop-up is open

If i press the button in the pop-up window, one more pop-up window will appear in the foreground.
Makes the last two windows inoperable while the second pop-up is open.

problem

It's possible on Windows, but not on the Raspberry Pi.

Behavior of Raspberry Pi (difference from Windows)
  • When you click on the back window, on Windows the back window becomes active only during the click, and on the Raspberry Pi the clicked window becomes active (after it becomes active)
  • With Raspberry Pi, you can close/minimize/maximize the back window, but with Windows you can't.
  • On Raspberry Pi, pressing the close button on win closes all front windows, but on Windows it doesn't.
  • With Raspberry Pi, if you press the close button of sub1_win while sub2_win is open, sub1_win will be closed but sub2_win will not be closed. Windows cannot close windows other than the foreground
  • If i click the window after clicking the background, the window you clicked will be activated on the Raspberry Pi, and the foreground window will be activated on Windows.
Behavior of Raspberry Pi (same as Windows)
  • Clicking on the background deactivates Tk () and Toplevel ()

(Active here means that the window is selected as shown in the attached image. The title bar is blue.)

Question

Ideally, it behaves like Windows, but is there a workaround to achieve the same behavior on the Raspberry Pi?

Source code
import tkinter as tk
def open_sub2_win (win, sub1_win):
    sub2_win = tk.Toplevel ()
    sub2_win.title ("sub2_win")
    sub2_win.geometry ("300x300 + 200 + 200")
    sub2_win.transient (sub1_win)
    sub2_win.grab_set ()
    sub2_win.focus_set ()
    sub2_win.protocol ("WM_DELETE_WINDOW", lambda: close_sub1_win (sub2_win))
def close_sub2_win (sub2_win):
    sub2_win.grab_release ()
    sub2_win.destroy ()
def open_sub1_win (win):
    sub1_win = tk.Toplevel ()
    sub1_win.title ("sub1_win")
    sub1_win.geometry ("300x300 + 100 + 100")
    sub1_win.transient (win)sub1_win.grab_set ()
    sub1_win.focus_set ()
    sub1_win.protocol ("WM_DELETE_WINDOW", lambda: close_sub1_win (sub1_win))
    btn = tk.Button (sub1_win, text = "open_sub2_win", command = lambda: open_sub2_win (win, sub1_win))
    btn.grid ()
def close_sub1_win (sub1_win):
    sub1_win.grab_release ()
    sub1_win.destroy ()
win = tk.Tk ()
win.title ("win")
win.geometry ("300x300 + 0 + 0")
btn = tk.Button (win, text = "open_sub1_win", command = lambda: open_sub1_win (win))
btn.grid ()
win.mainloop ()
Postscript

In Raspberry Pi, only the front window is closed and only the maximize button is effective.

import tkinter as tk
def open_sub2_win (win, sub1_win):
    global win_flag, sub1_flag, sub2_flag
    sub1_win.resizable (0, 0)
    win_flag = False
    sub1_flag = False
    sub2_flag = True
    sub2_win = tk.Toplevel ()
    sub2_win.title ("sub2_win")
    sub2_win.geometry ("300x300 + 200 + 200")
    sub2_win.transient (sub1_win)
    sub2_win.grab_set ()
    sub2_win.focus_set ()
    sub2_win.protocol ("WM_DELETE_WINDOW", lambda: close_sub2_win (sub1_win, sub2_win))

def close_sub2_win (sub1_win, sub2_win):
    global win_flag, sub1_flag, sub2_flag
    if sub2_flag == True:
        sub2_win.grab_release ()
        sub2_win.destroy ()
        win_flag = False
        sub1_flag = True
        sub2_flag = False
        sub1_win.resizable (1, 1)def open_sub1_win (win):
    global win_flag, sub1_flag, sub2_flag
    win.resizable (0, 0)
    win_flag = False
    sub1_flag = True
    sub2_flag = False
    sub1_win = tk.Toplevel ()
    sub1_win.title ("sub1_win")
    sub1_win.geometry ("300x300 + 100 + 100")
    sub1_win.transient (win)
    sub1_win.grab_set ()
    sub1_win.focus_set ()
    sub1_win.protocol ("WM_DELETE_WINDOW", lambda: close_sub1_win (win, sub1_win))
    btn = tk.Button (sub1_win, text = "open_sub2_win", command = lambda: open_sub2_win (win, sub1_win))
    btn.grid ()

def close_sub1_win (win, sub1_win):
    global win_flag, sub1_flag, sub2_flag
    if sub1_flag == True:
        sub1_win.grab_release ()
        sub1_win.destroy ()
        win_flag = True
        sub1_flag = False
        sub2_flag = False
        win.resizable (1, 1)
def close_win (win):
    global win_flag, sub1_flag, sub2_flag
    if win_flag == True:
        win.destroy ()
win_flag = True
sub1_flag = False
sub2_flag = False
win = tk.Tk ()
win.title ("win")
win.geometry ("300x300 + 0 + 0")
btn = tk.Button (win, text = "open_sub1_win", command = lambda: open_sub1_win (win))
btn.grid ()
win.protocol ("WM_DELETE_WINDOW", lambda: close_win (win))
win.mainloop ()
  • Answer # 1

    Since Raspberry Pi is hardware, you can't know the environment without writing the OS.
    However, as long as it works as expected on Windows, I don't think it is wrong in terms of source code.
    The front window of Raspberry Pi doesn't seem to change, so I wonder if it's a problem with the grab_set specifications.

    For the time being, I think the problem is that you can close, minimize, and maximize the back window, so why not consider disabling the hidden operation in open_sub1_win and open_sub2_win?
    I have to get it back when I close _ ..