Tkinter filedialog is stealing focus and not returning it without “Alt-tab” in Python 3.4.1

不问归期 提交于 2019-12-10 22:59:25

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!