Big Sharpie
Big Sharpie

Reputation: 849

Python tkinter 8.5 - How do you change focus from main window to a pop up window?

I'm new to tkinter and have a rather simple question. I would like to change focus from the first window, root, to the txt window after it pops up. I would also like the "OK" button to be focused as well. Of course, the idea is for the user to just be able to hit enter when they see this error. I'm terribly confused after various attempts with focus(), focus_set(), and takefocus. I'm not finding the documentation for this particularly helpful.

Below is my code:

from tkinter import *
from tkinter import ttk

def close(self):
    self.destroy()

def browse(*args):
    fileName = filedialog.askopenfilename()
    guiInputFile_entry.insert(0, fileName)
    return fileName

def formatInput(*args):
    if guiInputFile.get()[-4:] != ".txt": #checks for correct file extension (.txt)


    txt = Tk()
    txt.title("Error")         

    txtFrame = ttk.Frame(txt, padding="30 30 30 30")            
    txtFrame.grid(column=0, row=0, sticky=(N,W,E,S))
    txtFrame.columnconfigure(0, weight=1)
    txtFrame.rowconfigure(0, weight=1)

    ttk.Label(txtFrame, text = "Please enter a .txt file.\n").grid(column=2, row=1)
    okButton = ttk.Button(txtFrame, text = "OK", command = lambda: close(txt)).grid(column=2, row=2)
    return

    root = Tk()
    root.title("Cost Load Formatter")

    mainframe = ttk.Frame(root, padding="3 3 12 12")
    mainframe.grid(column=0, row=0, sticky=(N,W,E,S))
    mainframe.columnconfigure(0, weight=1)
    mainframe.rowconfigure(0, weight=1)

    guiInputFile = StringVar()

    guiInputFile_entry = ttk.Entry(mainframe, width=100, textvariable=guiInputFile)
    guiInputFile_entry.grid(column=1, row=2, stick=(W,E))

    ttk.Label(mainframe, text="Please enter the full filepath of the .txt file you wish to format:").grid(column=1, row=1)
    browseButton = ttk.Button(mainframe, text="Browse...", underline=0, command=browse).grid(column=2, row=2, sticky=W)
    formatButton = ttk.Button(mainframe, text="Format", underline=0, command= lambda: formatInput(guiInputFile)).grid(column=1, row=3)

    for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)

    guiInputFile_entry.focus()

    root.mainloop()

Thank you for any light you can shed.

Upvotes: 2

Views: 2897

Answers (2)

M_the_C
M_the_C

Reputation: 415

You're on the right track.

Firstly, you should only ever have one instance of Tk at a time. Tk is the object that controls the tkinter application, it just so happens that it also shows a window. Whenever you want a second window (third, fourth, etc.) you should use Toplevel. You can use it as you have used Tk, just pass it root:

txt = Toplevel(root)

It is just missing things like mainloop.

Secondly grid and pack do not return anything. So for example:

okButton = ttk.Button(txtFrame, text = "OK", command = lambda: close(txt)).grid(column=2, row=2)

Should be:

okButton = ttk.Button(txtFrame, text = "OK", command = lambda: close(txt))
okButton.grid(column=2, row=2)

But you should have been getting an error if that was causing you problems.

So to answer your main question, as you do with the Entry at the bottom you just call focus on the appropriate widget. focus_set does exactly the same, in fact if you look in Tkinter.py you will find focus_set is the name of the method, and focus is just an alias.

This will give the widget focus when the application has focus. If the application is not in focus there are ways to force it into the focus, but it is considered impolite and you should let the window manager control that.

Upvotes: 6

user1786981
user1786981

Reputation: 116

Instead of making a seperate Tk Window, you could use the built in tkmessagebox. This will give the window and OK button focus right out of the box.

Something like this:

tkMessageBox.showinfo("Warning","Please enter a .txt file.")

http://www.tutorialspoint.com/python/tk_messagebox.htm

Also, note I wrote this in Python 2.7, the syntax may be slightly different for Python 3, but the functionality should be the same.

Upvotes: 3

Related Questions