Home > Software design >  How to return a value from a function when it is used as a command function? How to close a user int
How to return a value from a function when it is used as a command function? How to close a user int

Time:03-11

I'm pretty new in python. I developed a simple GUI with tkinter for a file selection. When a button is pressed an open file dialog is activated and user can select a file from a folder. Here is my code:

import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd


# %% create a command associated to the window button
def open_file():
    initialDir = '/';
    fileTypes = (('Text files', '*.txt'), ('Csv files', '*.csv'), ('All files', '*.*'));
    Title = 'Choose a file';
    filename = str(fd.askopenfile(title=Title, filetypes=fileTypes));
        
    
# %% create a GUI
window = tk.Tk();
window.title('Tkinter GUI Open File Dialog');
window.resizable(False, False);
window.geometry('300x150');


# %% open file button
open_button = ttk.Button(window, text='Open a File',command=open_file);
open_button.grid(column=0, row=1, sticky='w', padx=10, pady=10)


# %% run window - automatic closing after 10 seconds
window.after(10000,lambda:window.destroy())
window.mainloop();

I would like to get the filename of the selected file. Moreover, I would like to close the gui when the button is pressed and the filename becomes known. Thank you all!

CodePudding user response:

At this moment you assign it to local variable filename but if you add global filename inside function then it will assign to global variable.

It may be good to assign to global variable some default value at start - so it will exists even if you don't select file.

If you want only filename (instead of reference to opened file) then use askopenfilename instead of askopenfile

And if you click Cancel then askopenfilename should give None and it could be better to keep it as None instead of convert to string. And later you should check if filename is None to run code only if you really selected filename.

import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd

filename = None # default value in global variable

# %% create a command associated to the window button
def open_file():
    global filename  # inform function to use global variable instead of local one
    
    initialDir = '/'
    fileTypes = (('Text files', '*.txt'), ('Csv files', '*.csv'), ('All files', '*.*'))
    Title = 'Choose a file'
    
    # use askopenfilename instead of askopenfile to get only name
    
    filename = fd.askopenfilename(title=Title, filetypes=fileTypes)
        
    # destroy GUI
    window.destroy()
    
# %% create a GUI
window = tk.Tk()
window.title('Tkinter GUI Open File Dialog')
window.resizable(False, False)
window.geometry('300x150')

# %% open file button
open_button = ttk.Button(window, text='Open a File',command=open_file)
open_button.grid(column=0, row=1, sticky='w', padx=10, pady=10)

# %% run window - automatic closing after 10 seconds
window.after(10000, window.destroy)
window.mainloop()

if filename:  # check if filename was really selected
    print('selected:', filename)
else:
    print("you didn't select filename")

If you want to keep all in function then it may need to use global in all functions

import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd

def get_filename():
    global filename
    
    filename = None # default value in global variable
    
    # %% create a command associated to the window button
    def open_file():
        global filename  # inform function to use global variable instead of local one
        
        initialDir = '/'
        fileTypes = (('Text files', '*.txt'), ('Csv files', '*.csv'), ('All files', '*.*'))
        Title = 'Choose a file'
        
        # use askopenfilename instead of askopenfile to get only name
        
        filename = fd.askopenfilename(title=Title, filetypes=fileTypes)
            
        window.destroy()
        
    # %% create a GUI
    window = tk.Tk()
    window.title('Tkinter GUI Open File Dialog')
    window.resizable(False, False)
    window.geometry('300x150')
    
    # %% open file button
    open_button = ttk.Button(window, text='Open a File',command=open_file)
    open_button.grid(column=0, row=1, sticky='w', padx=10, pady=10)
    
    # %% run window - automatic closing after 10 seconds
    window.after(10000, window.destroy)
    window.mainloop()
    
    return filename

# --- main ---

filename = get_filename()

if filename:  # check if filename was really selected
    print('selected:', filename)
else:
    print("you didn't select filename")

Popular method is also to create main window, hide it and directly run askopenfilename without button

import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd

def get_filename():
    global filename
    
    filename = None # default value in global variable
    
    # %% create a command associated to the window button
    def open_file():
        global filename  # inform function to use global variable instead of local one
        
        initialDir = '/'
        fileTypes = (('Text files', '*.txt'), ('Csv files', '*.csv'), ('All files', '*.*'))
        Title = 'Choose a file'
        
        # use askopenfilename instead of askopenfile to get only name
        
        filename = fd.askopenfilename(title=Title, filetypes=fileTypes)
            
        window.destroy()
        
    # %% create a GUI
    window = tk.Tk()
    
    #window.iconify()  # minimize to icon
    window.withdraw()  # hide it 
    
    window.after(10000, window.destroy)
    
    open_file()
    
    window.mainloop()
    
    return filename

# --- main ---

filename = get_filename()

if filename:  # check if filename was really selected
    print('selected:', filename)
else:
    print("you didn't select filename")
  • Related