I want to open multiple files (at least two) and store them into individual variables so I could then merge them using pandas, but all done by the click of a tkinter button. I have been stuck on this for two days now. I know I should be using Classes(OOP) python, but this isn't my forte as I am still a beginner...any help in the right direction will be appreciated. My code snippets:
importing all libraries
import tkinter
from sys import path
from tkinter import *
from tkinter import ttk, messagebox
from tkinter import filedialog as fd
from tkinter.messagebox import showinfo
from tkinter.messagebox import showerror
from tkinter.filedialog import asksaveasfile
from PIL import ImageTk, Image
import pandas as pd
browse_button = Button(btn_frame, text='Browse File', command=lambda: file_dialog(),
font=('helvetica', 10, 'bold'), bg='#ebdec5')
browse_button.grid(row=0, column=1, padx=10, pady=30)
load_button = Button(btn_frame, text='Load Data', command=lambda: merge_files(),
font=('helvetica', 10, 'bold'), bg='#ebdec5')
load_button.grid(row=0, column=2, padx=10, pady=40)
label_file = Label(btn_frame, text=browse_filetxt, font=('helvetica', 9, 'bold'), bg='#ebdec5')
label_file.place(rely=0, relx=0)
## file dialog to load files,how to load more than one, and and assign variables that can be used...
def file_dialog():
try:
file_name = fd.askopenfilename(initialdir='/',
title='Select a file',
filetypes=(('csv files', '*.csv'), ('All files', '*.*')))
except FileNotFoundError:
tkinter.messagebox.showerror('Information', "File not found")
return None
label_file['text'] = file_name
def merge_files():
global df
file_path = label_file['text']
try:
csv_filename = r'{}'.format(file_path)
df = pd.read_csv(csv_filename, delimiter=',')
# How to place files into variables.....
# what goes here..Please help
except ValueError:
tkinter.messagebox.showerror('Information', 'File is invalid')
return None
except FileNotFoundError:
tkinter.messagebox.showerror('Information', "File not found")
## I want to load two ore more files, put them into different variables, then use the variables,
# to merge both csv files using pandas......
CodePudding user response:
You should use list to keep all selected files. This way you may have any number of files and you can use for
-loop to work with all filenames
all_files = []
and when you select file
def file_dialog():
global all_files
try:
file_name = fd.askopenfilename(initialdir='/home/furas/test',
title='Select a file',
filetypes=(('csv files', '*.csv'), ('All files', '*.*')))
except FileNotFoundError:
tkinter.messagebox.showerror('Information', "File not found")
return
# check if not pressed `Cancel`
if file_name:
all_files.append( file_name )
And later you cand merge them
df = pd.DataFrame() # create new empty dataframe
for filename in all_files:
print('filename:', filename)
try:
new_df = pd.read_csv(filename, delimiter=',')
df = df.append(new_df)
except ValueError:
tkinter.messagebox.showerror('Information', 'File is invalid')
except FileNotFoundError:
tkinter.messagebox.showerror('Information', "File not found")
print(df.to_string())
Minimal working example:
import tkinter as tk
from tkinter import filedialog as fd
import pandas as pd
# --- functions ---
def file_dialog():
global all_files
print('[file_dialog]')
try:
file_name = fd.askopenfilename(initialdir='/home/furas/test',
title='Select a file',
filetypes=(('csv files', '*.csv'), ('All files', '*.*')))
except FileNotFoundError:
tkinter.messagebox.showerror('Information', "File not found")
return
# check if not pressed `Cancel`
if file_name:
all_files.append( file_name )
def merge_files():
global df
global all_files
print('[merge_files]')
df = pd.DataFrame() # create new empty dataframe
for filename in all_files:
print('filename:', filename)
try:
new_df = pd.read_csv(filename, delimiter=',')
except ValueError:
tkinter.messagebox.showerror('Information', 'File is invalid')
except FileNotFoundError:
tkinter.messagebox.showerror('Information', "File not found")
df = df.append(new_df)
print(df.to_string())
# remove all filenames
all_files = []
# --- main ---
df = pd.DataFrame() # create empty dataframe at start (as default value)
all_files = [] # create empty list at start (as default value)
root = tk.Tk()
browse_button = tk.Button(root, text='Browse File', command=file_dialog)
browse_button.pack(fill='x')
load_button = tk.Button(root, text='Load Data', command=merge_files)
load_button.pack(fill='x')
root.mainloop()
EDIT:
There is also askopenfilenames
with char s
at the end to select many filenames at once.
It gives list/tuple with all selected filenames which you could assign to global variable (and replace all previous filenames) or use extend()
or =
to add filenames to existing list
file_names = fd.askopenfilenames(...)
# check if not pressed `Cancel`
if file_names:
#all_files.extend( file_names ) # add to existing list
#all_files = file_names # add to existing list
all_files = file_names # replace previous list