#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()