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()
Related
This question already has answers here:
How do I get the Entry's value in tkinter?
(2 answers)
Closed 17 days ago.
enter image description here
when i write in the execution's entry i want this to be saved in another text file
how ?
and this is my code
from tkinter import ttk
from tkinter import *
root = Tk()
label1=ttk.Label(root,text="Type your message : ",font="classic")
label1.pack()
entry1=ttk.Entry(root,width=70)
entry1.pack()
button=ttk.Button(root,text="Send",padding=7,cursor="hand2")
button.pack()
def Bclick () :
entry1.delete(0,END)
print("sent")
button.config(command=Bclick)
file = input("yo :")
root.mainloop()
with open('text','w') as myfile :
myfile.write(file)
To get the value from an Entry widget, you need to use its get method, e.g.,
from tkinter import ttk
from tkinter import *
root = Tk()
label1 = ttk.Label(root, text="Type your message : ", font="classic")
label1.pack()
entry1 = ttk.Entry(root, width=70)
entry1.pack()
button = ttk.Button(root, text="Send", padding=7, cursor="hand2")
button.pack()
def Bclick():
entryvalue = entry1.get() # get what's in the Entry widget before clearing it
entry1.delete(0,END)
print("sent")
# write the value to a file
with open("text", "w") as myfile:
myfile.write(entryvalue) # write it to your file
button.config(command=Bclick)
#file = input("yo :") # not sure what this was for, so I've commented it out
root.mainloop()
After this, your file text should contain whatever you entered into the Entry box.
What your current code is doing is building the interface then it collects input through the terminal and writes it to a file, and then finally it displays the window to the user.
What you want to do instead is inside of your buttons callback method, collect the input from the Entry widget, and save whatever it contains in the your buttons callback.
from tkinter import ttk
from tkinter import *
filename = "MyTextFile.txt"
root = Tk()
label1=ttk.Label(root,text="Type your message : ",font="classic")
label1.pack()
entry1=ttk.Entry(root,width=70)
entry1.pack()
button=ttk.Button(root,text="Send",padding=7,cursor="hand2")
button.pack()
def Bclick():
text = entry1.get()
with open(filename, "wt") as fd:
fd.write(text)
entry1.delete(0,END)
print("sent")
button.config(command=Bclick)
root.mainloop()
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.
This GUI allows the user to open the file browser and select the files you need, show it on the field blank and then open the file once open is pressed. I'm new to python and had tried placing print tkFileDialog.askopenfilename() at the self.filename but this results in a syntax error. Please help. Thanks!
My question is as follows:
1) Why does my file browser open twice upon pressing the "file browser" button.
2) Also, how do I state the directory of the file selected in the file blank instead of in the python command prompt?
I would like to open the file in the future after pressing the ok button.
from Tkinter import *
import csv
import tkFileDialog
class Window:
def __init__(self, master):
self.filename=""
csvfile=Label(root, text="Load File:").grid(row=1, column=0)
bar=Entry(master).grid(row=1, column=1)
#Buttons
y=12
self.cbutton= Button(root, text="OK", command=self.process_csv) #command refer to process_csv
y+=1
self.cbutton.grid(row=15, column=3, sticky = W + E)
self.bbutton= Button(root, text="File Browser", command=self.browsecsv) #open browser; refer to browsecsv
self.bbutton.grid(row=1, column=3)
def browsecsv(self):
from tkFileDialog import askopenfilename
Tk().withdraw()
self.filename = askopenfilename()
print tkFileDialog.askopenfilename() # print the file that you opened.
def callback():
abc = askopenfilename()
execfile("input.xlsx")
def process_csv(self):
if self.filename:
with open(self.filename, 'rb') as csvfile:
logreader = csv.reader(csvfile, delimiter=',', quotechar='|')
rownum=0
for row in logreader:
NumColumns = len(row)
rownum += 1
Matrix = [[0 for x in xrange(NumColumns)] for x in xrange(rownum)]
root = Tk()
window=Window(root)
root.mainloop()
Your both questions are connected. The problem is in your browsecsv(self) method. Your directory is already stored in self.filename, no need to call askopenfilename() again. That's the reason why the file browser opens twice. Moreover, to set text in your Entry, you need to assign it a text variable.
self.entryText = StringVar()
self.bar = Entry(root, textvariable=self.entryText ).grid(row=1, column=1)
Then, you can assign it to the Entry in your method:
def browsecsv(self):
from tkFileDialog import askopenfilename
Tk().withdraw()
self.filename = askopenfilename()
self.entryText.set(self.filename)
I'm just starting to use tkinter and it is a little difficult to handle it. Check this sample :
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import Tkinter as tk
import tkFileDialog
def openfile():
filename = tkFileDialog.askopenfilename(title="Open file")
return filename
window = tk.Tk()
tk.Button(window, text='Browse', command=openfile).pack()
window.mainloop()
I juste created a browse button which keep the file path in the variable "filename" in the function openfile(). How can i put the content of "filename" in a variable out of the function ?
For example I want to put it in the variable P and print it in a terminal
def openfile():
filename = tkFileDialog.askopenfilename(title="Open file")
return filename
window = tk.Tk()
tk.Button(window, text='Browse', command=openfile).pack()
window.mainloop()
P = "the file path in filename"
print P
I also also want to put the file path in a widget Entry(), and as same as below, get the text in the Entry widget in another global variable.
If someone knows, it would be nice.
There are at least two different ways of doing it:
1) Bundle your whole app in a class like this:
import Tkinter as tk
import tkFileDialog
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self) # create window
self.filename = "" # variable to store filename
tk.Button(self, text='Browse', command=self.openfile).pack()
tk.Button(self, text='Print filename', command=self.printfile).pack()
self.spinbox = tk.Spinbox(self, from_=0, to=10)
self.spinbox.pack(pady=10)
tk.Button(self, text='Print spinbox value', command=self.printspinbox).pack()
self.mainloop()
def printspinbox(self):
print(self.spinbox.get())
def openfile(self):
self.filename = tkFileDialog.askopenfilename(title="Open file")
def printfile(self):
print(self.filename)
if __name__ == '__main__':
App()
In this case, filename is an attribute of the App, so it is accessible from any function inside the class.
2) Use a global variable:
import Tkinter as tk
import tkFileDialog
def openfile():
global filename
filename = tkFileDialog.askopenfilename(title="Open file")
def printfile():
print(filename)
def printspinbox():
print(spinbox.get())
window = tk.Tk()
filename = "" # global variable
tk.Button(window, text='Browse', command=openfile).pack()
tk.Button(window, text='Print filename', command=printfile).pack()
spinbox = tk.Spinbox(window, from_=0, to=10)
spinbox.pack(pady=10)
tk.Button(window, text='Print spinbox value', command=printspinbox).pack()
window.mainloop()
I'm having trouble returning a variable from a tkinter Button command. Here is my code:
class trip_calculator:
def __init__(self):
file = self.gui()
def gui(self):
returned_values = {}
def open_file_dialog():
returned_values['filename'] = askopenfilename()
root = Tk()
Button(root, text='Browse', command= open_file_dialog).pack()
filepath = returned_values.get('filename')
root.mainloop()
return filepath
root.quit()
I just want to return the filepath of a text file. The tkinter window is open and I can browse and choose the file but it then doesn't return the path.
The way your code is now, filepath is assigned its value before your window even appears to the user. So there's no way the dictionary could contain the filename that the user eventually selects. The easiest fix is to put filepath = returned_values.get('filename') after mainloop, so it won't be assigned until mainloop ends when the user closes the window.
from Tkinter import *
from tkFileDialog import *
class trip_calculator:
def gui(self):
returned_values = {}
def open_file_dialog():
returned_values['filename'] = askopenfilename()
root = Tk()
Button(root, text='Browse', command= open_file_dialog).pack()
root.mainloop()
filepath = returned_values.get('filename')
return filepath
root.quit()
print(trip_calculator().gui())