0

I'm using Tkinter OptionMenu to create a Toplevel window. However, I found that after the window is created, if I move my cursor just a little bit, the focus will go back to my main screen (the little screen to the left) instead of the newly created Toplevel.

If I use a Button instead of an OptionMenu to do the same thing, the new Toplevel window is sent to the front correctly.

Here's the code that produces the bug:

import tkinter as tk

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.create_button()
        self.create_dropdown()

    def create_button(self):
        self.button = tk.Button(self)
        self.button["text"] = "Create Toplevel"
        # this works correctly, new topmost sent to the top
        self.button["command"] = self.create_toplevel
        self.button.pack(side="top")

    def create_dropdown(self):
        self.current_dropdown_option = tk.StringVar(self.master)
        self.current_dropdown_option.set("Choose an option")
        # this doesn't work correctly, the new Toplevel is sent to the back
        self.dropdown = tk.OptionMenu(self.master, self.current_dropdown_option,
                                      "Option 1", command=self.create_toplevel_for_dropdown)
        self.dropdown.pack(side="top")

    def create_toplevel(self):
        self.toplevel = tk.Toplevel(self.master)
        self.toplevel.geometry("600x600")

    def create_toplevel_for_dropdown(self, arg):
        self.toplevel = tk.Toplevel(self.master)
        self.toplevel.geometry("600x600")

root = tk.Tk()
app = Application(master=root)
app.mainloop()

The picture has two tkinter windows, the OptionMenu is on the left window and is focused. The right window is unfocued due to the bug described

I have tried a solution from https://stackoverflow.com/a/36191443/2860949 and it doesn't work.

Tested on macOS Catalina 10.15.5, python 3.7.6 from python.org.

1 Answers1

0

You can use this Toplevel_name.focus_set() method wherever you are creating the Toplevel. This method works with any widget for that matter, it moves the keyboard focus to the particular widget, which means that all keyboard events sent to the application will be routed to this widget.

For the complete list of basic widget methods refer https://effbot.org/tkinterbook/widget.htm.

Hope it helped, Cheers!

astqx
  • 2,058
  • 1
  • 10
  • 21
  • Thanks for the answer! However, this doesn't work for me. It seems that the new toplevel window takes focus for a while until I move my cursor. When I move my cursor, the focus goes back to the root. The `.focus_set()` does not help because the line is called when the new window is already taking focus. – Santi Santichaivekin Aug 14 '20 at 21:41