问题
First question here, but I've answered a few, so hopefully there'll be enough information here for someone to give me a pointer in the right direction.
I have the following code that will form part of an app I'm building. I want users to be able to enter their name and evaluate some images, scoring them using the slider. In order to define the source of the images, I want to select a folder using filedialog.askdirectory
so the user can verify the correct folder containing the images.
I've stripped out the buttons and the functions that record data to simplify this.
So, the problem I have is that when the window pops up, the filedialog appears and allows me to choose the folder. After I've chosen though, the Entry
fields are not able to be selected to allow the user to type in their name. If I navigate away from the window by Alt-tab or by clicking another window and going back, I can position the cursor and proceed as normal - obviously, this isn't ideal for my end-users.
Here is the filedialog popup shown here:
And the second window, which doesn't automatically take focus:
import tkinter as tk
from tkinter import filedialog
import numpy as np
class Model:
def __init__(self):
self.scores = []
self.position = 0
self.first_name = ""
self.last_name = ""
class WelcomeWindow:
def __init__(self, master):
button_width=25
button_height=10
self.master = master
self.frame = tk.Frame(self.master)
#self.file_dialog = tk.Frame(self.master)
self.directory = filedialog.askdirectory(parent=self.master)
self.canvas = tk.Canvas(self.frame,
height=600,
width=800
)
self.model = Model()
self.first_name_entry = tk.Entry(self.frame)
self.last_name_entry = tk.Entry(self.frame)
self.slider = tk.Scale(self.frame,
length=button_width * 20,
width=button_width * 2,
sliderlength=150,
showvalue=False,
from_=-3.00,
to=3.00,
orient="horizontal",
tickinterval=1,
label="Here is a slider",
resolution=0.01
)
self.frame.pack()
self.first_name_entry.pack()
self.last_name_entry.pack()
self.canvas.pack()
self.slider.pack()
def main():
root = tk.Tk()
win = WelcomeWindow(root)
root.mainloop()
main()
I've tried setting the takefocus
option for the frame
and for the first_name_entry
field to True
with no success. I've also tried adjusting the parent of self.directory
to self.frame
and that completely removes my ability to interact with the main window.
If I've left anything out, please leave a comment and I'll provide anything I can
回答1:
There is a known issues on Windows systems where using filedialog before the mainloop has had a chance to fully loop the first time causing this kind of focus issue.
Originally I solved this kind of issue using after()
to schedule the filedialog to happen sometime after the first loop has completed but thanks to fhdrsdg's comment there is a simpler method to fix this using update_idletasks()
.
Here is your code reworked to fix the focus issue and some general clean up.
import tkinter as tk
from tkinter import filedialog
class Model:
def __init__(self):
self.scores = []
self.position = 0
self.first_name = ""
self.last_name = ""
class WelcomeWindow(tk.Tk):
def __init__(self):
super().__init__()
button_width = 25
button_height = 10
self.frame = tk.Frame(self)
self.directory = ''
self.canvas = tk.Canvas(self.frame, height=600, width=800)
self.model = Model()
self.first_name_entry = tk.Entry(self.frame)
self.last_name_entry = tk.Entry(self.frame)
self.slider = tk.Scale(self.frame, length=button_width * 20, width=button_width * 2, sliderlength=150, showvalue=False,
from_=-3.00, to=3.00, orient="horizontal", tickinterval=1, label="Here is a slider", resolution=0.01)
self.frame.pack()
self.first_name_entry.pack()
self.last_name_entry.pack()
self.canvas.pack()
self.slider.pack()
self.update_idletasks() # adding this here fixes the focus issue
self.directory = filedialog.askdirectory()
def main():
WelcomeWindow().mainloop()
if __name__ == "__main__":
main()
来源:https://stackoverflow.com/questions/53763079/tkinter-filedialog-is-stealing-focus-and-not-returning-it-without-alt-tab-in-p