Display DataFrame in tkinter library - python

i want to create a simple GUI form, which asks user to browse file and then display result, i have wrote following code :
import numpy as np
import pandas as pd
from tkinter import *
from tkinter.filedialog import askopenfilename
def read_file():
filename =askopenfilename()
label1.insert(0,filename)
return
def display_file():
filename1 =label1.get()
data =pd.read_csv(filename1)
print(data.head())
root =Tk()
#root.withdraw()
label1 =Entry(root,width=100)
button =Button(root,text="Read csv file",command=read_file)
button1 =Button(root,text="Display file",command=display_file)
button.pack()
label1.pack()
button1.pack()
root.mainloop()
result is following image :
when i click read csv file, it gives me possibility to read file and result is like this :
now i need display part :
def display_file():
filename1 =label1.get()
data =pd.read_csv(filename1)
print(data.head())
this function just display files in working directory, but i need to show(5 rows of dataframe) in GUI form, let us suppose that file contains just two column - please tell me how to do? i have searched a lot but could not find exact solution (different solutions was presented and i was confused)

You have to add a Tkinter element where you want the data to be displayed (here, I choose Label) using a Variable element and set this element to hold your data from inside the display_file formula:
import numpy as np
import pandas as pd
from tkinter import *
from tkinter.filedialog import askopenfilename
def read_file():
filename = askopenfilename()
label1.insert(0, filename)
return
def display_file():
filename1 = label1.get()
data = pd.read_csv(filename1)
print(data.head())
pd_variable.set(data.head())
root = Tk()
# root.withdraw()
label1 = Entry(root, width=100)
button = Button(root, text="Read csv file", command=read_file)
button1 = Button(root, text="Display file", command=display_file)
pd_variable = Variable(root)
label2 = Label(root, textvariable=pd_variable)
button.pack()
label1.pack()
button1.pack()
label2.pack()
root.mainloop()

Related

Run a function on button command using tkinter

first of all, I'm a beginner. I have a basic script (get grades()) that takes a .csv file and specific class sections (min 1, max 3). I wrote this function to clean courses grades, and the output is a .txt containing only the student number, class section and grade. This text file is then ready to be upload to a system at my uni.
I'm trying to create a GUI for this script, but I'm stuck. Googling around, I managed to get a basic GUI, but even though I can enter the class sections and browse for a file, I cannot make it run my function. When I click on the button to the get the grades, the GUI crashes. Could you please point me in the right direction? Thank you in advance.
tkinter code
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo
import tkinter
from tkinter import *
from tkinter import filedialog as fd
from get_grades import get_grades
from functools import partial
# root window
root = tk.Tk()
root.geometry("500x450")
root.title('Grades')
# store sections
sections = tk.StringVar()
file_name = tk.StringVar()
def save_sections():
""" callback when the sections button clicked
"""
msg = f'You entered sections: {sections.get()}'
showinfo(
title='Information',
message=msg
)
# Sign in frame
signin = ttk.Frame(root)
signin.pack(padx=10, pady=10, fill='x', expand=True)
# sections
sections_label = ttk.Label(signin, text="sections:")
sections_label.pack(fill='x', expand=True)
sections_entry = ttk.Entry(signin, textvariable=sections)
sections_entry.pack(fill='x', expand=True)
sections_entry.focus()
# login button
section_button = ttk.Button(signin, text="save sections", command=save_sections)
section_button.pack(fill='x', expand=True, pady=10)
def get_file_name(file_entry):
file_name = fd.askopenfilename(title="Select file", filetypes=(("CSV Files", "*.csv"),))
file_entry.delete(0, END)
file_entry.insert(0, file_name)
entry_csv = Entry(root, text="", width=50)
entry_csv.pack(fill='x', expand=True)
file_label = ttk.Label(root, text="Input CSV")
file_button = ttk.Button(root, text="Browse...", width=10, command=lambda: get_file_name(entry_csv))
file_button.pack(fill='x', expand=True, pady=10)
grades_button = ttk.Button(root, text="Get grades", width=10, command=lambda: get_grades(entry_csv, sections))
grades_button.pack(fill='x', expand=True, pady=10)
# infinite loop
root.mainloop()
get_grades.py
import pandas as pd
from datetime import datetime
def get_grades(file, section1=True, section2=False, section3=False):
sections = []
if section1:
sections.append(section1)
if section2:
sections.append(section2)
if section3:
sections.append(section3)
else:
return "missing sections"
# get file
df = pd.read_csv(file)
# delete the first two rows
df = df.drop([df.index[0], df.index[1]])
# important columns are "SIS User ID", "Section", and the name of the test, which changes by course
# first, rename the assignment column
df = df.rename(columns={df.columns[5]: "Grade"})
df = df[df.Student != "Student, Test"]
# select columns
df = df[["SIS User ID", "Section", "Grade"]]
df = df[df['Section'].isin(sections)]
# cleaning
df = df.replace("0.0", "NVD")
df = df.fillna("NA")
# deleting decimal
df['SIS User ID'] = df['SIS User ID'].astype(str).apply(lambda x: x.replace('.0', ''))
# save to txt and csv
# file name
date_time = datetime.now().strftime("%Y_%m_%d-%I_%M_%S_%p")
filename = str(date_time) + "_" + str(sections)
df.to_csv(str(filename + ' .txt'), sep='\t', index=False)
print("done! file " + str(filename) + ".txt saved")
You are passing an Entry widget and a StringVar to your function. But your function expects string objects.
You have to get the values of your entry box and StringVar. Luckily, the method is called the same for both cases. It's the .get() method.
grades_button = ttk.Button(root, text="Get grades", width=10, command=lambda: get_grades(entry_csv.get(), sections.get()))
This should pass the correct values to get_grades(). But to be sure, you should print the values to console, just to check. This would also have hinted at the problem you had with your code.

tkinter: AttributeError: 'Button' object has no attribute 'get' when trying to access file from filedialog.askopenfilename

So I have something like this:
import tkinter as tk
from tkinter import ttk
from tkinter import filedialog
import pandas as pd
window = tk.Tk()
window.geometry('350x240')
def open_file():
temp_file = filedialog.askopenfilename(title="Open file", filetypes=[("Excel files", "*.csv")])
temp_file = open(temp_file, "r")
Proj_df = pd.read_csv(temp_file)
open_button = ttk.Button(text='Select File...', command=open_file)
open_button.grid(column=1, row=1)
def get_info():
x = open_button.get()
print (x)
button1 = ttk.Button(text='Get Information', command=get_info)
button1.grid(column=0, row=2)
What I'm trying to do is to store the DataFrame created in open_file() to use it in get_info(). I'm getting:
AttributeError: 'Button' object has no attribute 'get'
How could I access the DataFrame created in open_button?
This might help you along the way. You can set a tk.StringVar then use to retrieve, store, and access items that are input through various tk/ttk widgets. Also I suppose you might want to store your inbound file? I ran this attempt simply reading in the csv, not using pandas.
import tkinter as tk
from tkinter import filedialog, ttk
#import pandas as pd
window = tk.Tk()
window.geometry('350x240')
tkvar1 = tk.StringVar(window)
def open_file():
temp_file = filedialog.askopenfilename(title="Open file", filetypes=[("Excel files", "*.csv")])
temp_file = open(temp_file, "r")
tkvar1.set(temp_file.read())
#Proj_df = pd.read_csv(temp_file)
open_button = ttk.Button(text='Select File...', command=open_file)
open_button.grid(column=1, row=1)
def get_info():
x = tkvar1.get()
print (x)
button1 = ttk.Button(text='Get Information', command=get_info)
button1.grid(column=0, row=2)
window.mainloop()

Update Label in Tkinter to prevent overlapping text

I'm new to Tkinter and I'm trying to create a simple Button that opens a file dialog box, where the user chooses which CSV file to open. Under the button there is a label that should display the file path for the file that was opened.
When I click on the button once, everything works as expected. However, if I click on it a second time and select a different file, the new filepath overlaps with the previous one, instead of replacing it.
Here is the code for the implementation function (please let me know if you need more bits of code for context):
def open_csv_file():
global df
global filename
global initialdir
initialdir = r"C:\Users\stefa\Documents\final project models\Case A"
filename = filedialog.askopenfilename(initialdir=initialdir,
title='Select a file', filetypes = (("CSV files","*.csv"),("All files","*.*")))
df = pd.read_csv(os.path.join(initialdir,filename))
lbl_ok = tk.Label(tab2, text = ' ') #tab2 is a ttk.Notebook tab
lbl_ok.config(text='Opened file: ' + filename)
lbl_ok.grid(row=0,column=1)
Here is how to do it with .config(), create the label instance just once (can then grid as much as you want but probably just do that once too), then just configure the text:
from tkinter import Tk, Button, Label, filedialog
def open_file():
filename = filedialog.askopenfilename()
lbl.config(text=f'Opened file: {filename}')
root = Tk()
Button(root, text='Open File', command=open_file).grid()
lbl = Label(root)
lbl.grid()
root.mainloop()
You can use a StringVar for this. Here is an example that may help you:
from tkinter import *
from tkinter.filedialog import askopenfilename
root = Tk()
root.geometry('200x200')
def openCsv():
csvPath.set(askopenfilename())
csvPath = StringVar()
entry = Entry(root, text=csvPath)
entry.grid(column=0, row=0)
btnOpen = Button(root, text='Browse Folder', command=openCsv)
btnOpen.grid(column=1, row=0)
root.mainloop()

Browse Functionality in Tkinter

I'm trying the implement the browse functionality in Tkinter, I'm able to implement the browse file option, however, after selecting the file at a particular location it's displaying file location on the console, how to print that location on the label?
At the following place, file_location or file_name should be printed.
entry_1.insert(0, 'File_location')
For e.g. the file location is
Path with file name C:\Users\Desktop\test\test.txt
, so this file location should be printed on the label instead of the console.
And along with that, if I want only a path without a file name then how it can be done?
Path without file name. C:\Users\Desktop\test
What extra functionality do I need to add in order to implement this feature? Any help would be appreciated.
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from io import StringIO
import sys
import os
root = Tk()
root.geometry('700x650')
root.title("Data Form")
def file_opener():
input = filedialog.askopenfiles(initialdir="/")
print(input)
for i in input:
print(i)
label_1 = Label(root, text="Location",width=20,font=("bold", 10))
label_1.place(x=65,y=130)
x= Button(root, text='Browse',command=file_opener,width=6,bg='gray',fg='white')
x.place(x=575,y=130)
entry_1 = Entry(root)
entry_1.place(x=240,y=130,height=20, width=300)
entry_1.insert(0, 'File_location')
root.mainloop()
Instead of using
filedialog.askopenfile(initialdir="/")
use
filedialog.askopenfilename(initialdir="/")
if you want to select multiple files and get a tuple as the input use
filedialog.askopenfilenames(initialdir="/")
And for the path without the file name use this
import os
os.path.dirname(input)
you can Insert the text to the Entry by using this
Updated:
entry_1.delete(0, END)
entry_1.insert(0, input[0])
Full Modified code
(Updated:)
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
from io import StringIO
import sys
import os
root = Tk()
root.geometry('700x650')
root.title("Data Form")
def file_opener():
# input = filedialog.askopenfilenames(initialdir="/") # for selecting multiple files
input = filedialog.askopenfilename(initialdir="/")
entry_1.delete(0, END)
entry_1.insert(0, input)
label_1 = Label(root, text="Location", width=20, font=("bold", 10))
label_1.place(x=65, y=130)
x = Button(root, text='Browse', command=file_opener, width=6, bg='gray', fg='white')
x.place(x=575, y=130)
entry_1 = Entry(root)
entry_1.place(x=240, y=130, height=20, width=300)
entry_1.insert(0, 'File_location')
root.mainloop()

How to access a function dataframe variable from outside the function in Python?

In the following code I get to select an excel file using a tkinter button.
I'm using a function to read the excel file and import data and convert to dataframe.
The problem is I don't have access to the dataframe outside the function although it's a global variable, therefore I can't continue with the rest of stuff.
I can now access the df variable, but not as a DataFrame which appears to be empty.
What is best to do to get around this ?
import tkinter as tk
from tkinter import filedialog, ttk
import pandas as pd
root=tk.Tk()
root.title("THIS IS MY FIRST APPLICATION")
root.geometry("600x300")
text_import = ("Choose your file: ")
df = pd.DataFrame()
# browse file and import data
def getExcel ():
global df
import_file_path = filedialog.askopenfilename()
data1 = pd.read_excel(import_file_path)
df = pd.DataFrame(data1)
print(df)
# create button
my_button = tk.Button(root, text = text_import, width = 15, height = 2,
command = getExcel)
my_button.pack(pady=10)
my_button.place(x = 200, y = 75)
print(df.dtypes)
root.mainloop()
When print(df.dtypes) is executed, no file is loaded yet and so it is empty. You should call it inside a function which should be called after a file is loaded:
import tkinter as tk
from tkinter import filedialog, ttk
import pandas as pd
root = tk.Tk()
root.title("THIS IS MY FIRST APPLICATION")
root.geometry("600x300")
text_import = "Choose your file: "
df = None
# browse file and import data
def getExcel():
global df
import_file_path = filedialog.askopenfilename()
if import_file_path:
df = pd.read_excel(import_file_path)
print(df)
# create button
my_button = tk.Button(root, text=text_import, width=15, height=2, command=getExcel)
#my_button.pack(pady=10)
my_button.place(x=200, y=75)
def showExcel():
if df is not None:
# a file is loaded
print(df.dtypes)
tk.Button(root, text="Show File Data", width=15, height=2, command=showExcel).place(x=200, y=150)
root.mainloop()

Categories

Resources