简体   繁体   中英

Tkinter filedialog breaks entry widgets

tl;dr: When the application calls tkinter.filedialog , entry fields do not properly focus.

Long explanation:

When initializing a tkinter application, the entry fields are enabled by default. Their state is tk.ENABLED , they can be focused on by scrolling through fields with tab , and, most importantly, they can be clicked on to select the field.

For some reason, this behavior is broken by calling tkinter.filedialog . If a method of tkinter.filedialog is called, such as askdirectory or askopenfile() , the entry field will still have the tk.ENABLED state, and the background will be properly styled, but clicking on the entry field will not insert the cursor or select the field. Typing, of course, does not register.

This can be worked around by toggling to a different window and toggling back. However, the file dialog windows (properly) return the user directly back to the main window, and so users are always presented with a main window that appears to be locked up.

See this example:

import tkinter as tk
from tkinter import filedialog

BR8K = True

root = tk.Tk()

if BR8K:
    filedialog.askdirectory()

entry = tk.Entry(root, takefocus=True, highlightthickness=2)
entry.grid(sticky="WE")


root.mainloop()

Here, the code behaves properly if BR8K is False , and incorrectly if BR8K is True .

(Note: In a production environment, this would be object oriented. The issue persists in an object oriented environment.)

This is a known issues resulting from a dialog window being called prior to the mainloop() being reached for the first time.

The simplest way to fix this is to add update_idletask() before the dialog.

Try this:

import tkinter as tk
from tkinter import filedialog

BR8K = True

root = tk.Tk()
# By adding this you avoid the focus breaking issue of calling dialog before the mainloop() has had its first loop.
root.update_idletasks() 

if BR8K:
    filedialog.askdirectory()

entry = tk.Entry(root, takefocus=True, highlightthickness=2)
entry.grid(sticky="WE")


root.mainloop()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM