Возвращает путь к файлу из tkinter filedialog

#python #tkinter

#python #tkinter

Вопрос:

Я пытаюсь создать простой графический интерфейс с помощью tkinter, который позволяет пользователям выбирать файл с помощью окна браузера файлов, которое будет являться входом для другого скрипта python. Я хотел бы иметь виджет ввода, который позволяет пользователю вводить путь к файлу вручную. Если пользователь решит выбрать файл из браузера, а не вводить его, я бы хотел, чтобы виджет ввода отображал выбранный путь к файлу.

Приведенный ниже код может создать форму (я не сильно форматировал виджеты) и отобразить диалоговое окно файла. С помощью функции ‘show_file_browser’ я могу вернуть весь путь к файлу. Проблема, с которой я сталкиваюсь, заключается в вставке этого пути к файлу в виджет ввода.

Ошибка, которую я получаю в настоящее время:

 NameError: name 'filepath' is not defined
  

Это вызвано функцией ‘first_browser’. Поскольку ‘filepath’ объявлен в функции ‘init_window’, он не определен, когда я пытаюсь установить его в ‘first_browser’. Если не считать превращения ‘filepath’ в глобальную переменную (что, я не уверен, решит проблему), есть ли простой способ выполнить задачу, которую я пытаюсь выполнить?

 import tkinter as tk
from tkinter import filedialog

class Window(tk.Frame):
    def __init__(self, master = None):
        tk.Frame.__init__(self, master)
        self.master = master
        self.init_window()

    def init_window(self):
        self.master.title("Form Title")
        self.pack(fill = 'both', expand = 1)

        filepath = tk.StringVar()

        quitButton = tk.Button(self, text = 'Quit',
                               command = self.close_window)
        quitButton.place(x = 0, y = 0)

        browseButton = tk.Button(self, text = 'Browse',
                                 command = self.first_browser)
        browseButton.place(x = 0, y = 30)

        filepathText = tk.Entry(self, textvariable = filepath)
        filepathText.pack()

    def close_window(self):
        form.destroy()

    def show_file_browser(self):
        self.filename = filedialog.askopenfilename()
        return self.filename

    def first_browser(self):
        filepath.set = self.show_file_browser()

form = tk.Tk()
form.geometry("250x250")
form.resizable(0, 0)

app = Window(form)

form.mainloop()

  

Ответ №1:

Попробуйте с этим

 class Window(tk.Frame):
    def __init__(self, master = None):
        tk.Frame.__init__(self, master)
        self.master = master
        self.init_window()


    def init_window(self):
        self.master.title("Form Title")
        self.pack(fill = 'both', expand = 1)

        self.filepath = tk.StringVar()

        quitButton = tk.Button(self, text = 'Quit',
                               command = self.close_window)
        quitButton.place(x = 0, y = 0)

        browseButton = tk.Button(self, text = 'Browse',
                                 command = self.first_browser)
        browseButton.place(x = 0, y = 30)

        filepathText = tk.Entry(self, textvariable = self.filepath)
        filepathText.pack()

    def close_window(self):
        form.destroy()

    def show_file_browser(self):
        self.filename = filedialog.askopenfilename()
        return self.filename

    def first_browser(self):
        file = self.show_file_browser()
        self.filepath.set(file)
  

для создания a "global" variable внутри класса вы должны добавить self. перед именем переменной.
В вашем коде вы написали внутри first_browser(self) функции
filepath.set = self.show_file_browser() , но вы не можете этого сделать, прежде чем вам нужно будет принять значение, возвращаемое self.show_file_browser() таким value=self.show_file_browser() образом, и после того, как вы сможете установить переменную ввода в это значение

Ответ №2:

«Если пользователь решит выбрать файл из браузера, а не вводить его, я бы хотел, чтобы виджет ввода отображал выбранный путь к файлу».

Решение этой проблемы заключается в следующем: вы можете соответствующим образом внедрить код в свой проект.

 from tkinter import messagebox
from tkinter import filedialog

def fileNameToEntry():

      files = [('All Files', '*.*'), 
             ('Python Files', '*.py'),
             ('Text Document', '*.txt')]
      filename = filedialog.askopenfilename(initialdir = "/",
                                          title = "Select a File",
                                          filetypes = files,
                                          defaultextension = files)
      filename = filename.strip()

#User select cancel
      if (len(filename) == 0):
         messagebox.showinfo("show info", "you must select a file")       
         return
#selection go to Entry widget
      else:
         myStrVar.set(filename)
      
root = Tk()
root.title("select and show file path in Entry widget")
lblFileName  = Label(root, text = "Selected File Name", width = 24)
lblFileName.grid(padx = 3, pady = 5, row = 0, column = 0)

#make global variable to access anywhere
global myStrVar
myStrVar = StringVar()
txtFileName  = Entry(root, textvariable = myStrVar, width = 60, font = ('bold'))
txtFileName.grid(padx = 3, pady = 5, row = 0, column = 1)
btnGetFile = Button(root, text = "Get File Name", width = 15,
    command = fileNameToEntry)
btnGetFile.grid(padx = 5, pady = 5, row = 1, column = 0)
root.mainloop()
  

Окно вывода