Home > OS >  Opening at least two csv files and merging them using tkinter button
Opening at least two csv files and merging them using tkinter button

Time:04-11

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
  • Related