您可以保证子窗口将具有filedialog 的焦点,就像这样。
image = fido.askopenfilename( parent = child, title = "Pick an image" )
Transient 应用于子窗口将使子窗口坐在父窗口的前面,但不会在加载数据后阻止父窗口成为焦点。
我已经设置了程序,所以你可以测试它,只需将条件语句设置为 True 并从文件对话框中删除 parent = child。
已扩展代码以全面测试 tkinter 的行为
Tkinter 实验:
测试Tk 和Toplevel 窗口的焦点控制和图像显示时
使用tk.filedialog.askopenfilename
结论:
除非显式设置在 filedialog 关闭后,最终焦点将始终转到 filedialog 中定义的小部件(默认 = 父级)。
将子级设置为瞬态不会影响最终焦点。
另外,如果 child 是 tk.Tk(),那么 tk.PhotoImage 需要 file = image 和 master = parent|child,否则会抛出 _tkinter.TclError: image "pyimage1" doesn't exist 错误。
如果孩子是tk.Toplevel(),那么tk.PhotoImage 只需要file = image 就可以成功显示照片!
import os
import tkinter as tk
from tkinter import filedialog as fido
parent = tk.Tk()
parent.title("Parent")
# Give tkinter time to compute parent size and position
parent.update()
# Extract window dimensions from parent
x, y, w = parent.winfo_x(), parent.winfo_y(), parent.winfo_width()
if False:
# Create child as `Toplevel`
child = tk.Toplevel(parent)
child.title("Child")
# Test usefulness of transient in controlling focus
if True:
child.transient(parent)
else:
# Create child as `Tk
child = tk.Tk()
child.title("Child")
# Place both windows side by side
child.geometry( f"+{x+w+10}+{y}" )
if False:
# TEST 1: Focus will ulitmately go to parent
child.focus_set()
image = fido.askopenfilename( title = "Pick an image" )
else:
# TEST 2: Focus will ulitmately go to child
parent.focus_set()
image = fido.askopenfilename( parent = child, title = "Pick an image" )
# Demonstrate that placing data (image) in child will not alter the focus
if image:
if True:
# Try loading image method #1: Will show image
photo = tk.PhotoImage(master = child, file = image)
else:
# Try loading image method #2: Will throw error
photo = tk.PhotoImage(file = image)
# Display photo in `label`
label = tk.Label(
child, image = photo, foreground = "white", font = "Consolas 20 normal",
compound = tk.CENTER, text = os.path.split( image )[1])
label.pack(fill=tk.BOTH, expand=True)
parent.mainloop()