I have a file dialog to open a file in tkinter. I am getting the file name using tkinter using askopenfile() as shown below. Now I want to be able to access the path to the file outside the file_opener() function.
from tkinter import *
from tkinter import filedialog as fd
base = Tk()
base.geometry('150x150')
def file_opener():
file = fd.askopenfile()
if file:
y = file.name
def file():
f = open(y,'r') #Here i want to use value of y from above function
x = Button(base, text='Select a .txt/.csv file', command=lambda: file_opener())
x.pack()
mainloop()
You need to use return to return values. Modified code:
from tkinter import *
from tkinter import filedialog as fd
base = Tk()
base.geometry('150x150')
def file_opener():
file = fd.askopenfile()
if file:
return file.name
def file():
f=open(file_opener(),'r') #Here i want to use value of y from above function
print(f.read())
x = Button(base, text ='Select a .txt/.csv file', command = lambda:file())
x.pack()
mainloop()
Related
Good day folks,
I created a simple GUI that let's the user browse through their files with tkinter's filedialog.
After picking one, python reads the data from the (excel) file, and with that creates a new .txt file.
Now after doing that, I would like python to make that .txt file pop up, so that the user gets to see the result.
How do I do this?
Edit for the bot-moderator- he wanted code examples:
File1.py
from contextlib import nullcontext
import File2 as tp
import tkinter as tk
from tkinter import StringVar, messagebox
from tkinter import filedialog
filename = None
def pickFile():
global filename
filename = filedialog.askopenfilename()
#Creating main window
master = tk.Tk()
masterWidth = 350
masterHeight = 250
master.iconbitmap('C:\...')#directory
master.title('Title')
# get the screen dimension
screen_width = master.winfo_screenwidth()
screen_height = master.winfo_screenheight()
# find the center point
center_x = int(screen_width/2 - masterWidth / 2)
center_y = int(screen_height/2 - masterHeight / 2)-100
# set the position of the window to the center of the screen
master.geometry(f'{masterWidth}x{masterHeight}+{center_x}+{center_y}')
#Creating startbutton
startButton = tk.Button (master, text="Start", height=1, width=3, command=lambda: tp.readFile(filename))
#Creating bladerknop
browseButton = tk.Button (master, text='browse...', command=pickFile)
browseLabel = tk.Label(master, text='Choose a file')
startButton.place(x=175,y=200)
browseButton.place(x=210,y=50)
browseLabel.place (x=110,y=52)
master.mainloop()
File2.py
import pandas as pd
import tkinter as tk
from tkinter import messagebox
#declaring variables for later use
data = None
def missingValues(path):
if path is not None:
data = pd.read_excel(path, header=None)
return data
else:
messagebox.showinfo('No file chosen', 'Choose a file first.')
def readFile(path):
data = missingValues(path)
with open("C:\...\newFile.txt", 'w') as newTxt:
count = 0
for index, row in data.iterrows():
code = data.loc[count,0]
price = toEightBits(data.loc[count,1])
newTxt.write(str(code))
newTxt.write(str(price))
newTxt.write("\n")
count += 1
newTxt.close()
I would like to create a pyton script that takes an excel file (provided by the user), run a script, and save this excel file (with a file name provided by the user).
I would like to implement some buttons using Tkinter to enable non-programmers to easily use my algorithm.
I tried to create a ''load data'' and ''display data'' button (I took a code online) that both work.
However I didn't manage to run the script on the database imported (as I don't know how to access it)
I didnt manage to create a button that enables the user to choose the name of the file they want to save it to.
import tkinter as tk
from tkinter import ttk
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import asksaveasfilename
from tkinter.messagebox import showerror
import pandas as pd
import csv
# --- classes ---
class MyWindow:
def __init__(self, parent):
self.parent = parent
self.filename = None
self.df = None
self.text = tk.Text(self.parent)
self.text.pack()
self.button = tk.Button(self.parent, text='LOAD DATA', command=self.load)
self.button.pack()
self.button = tk.Button(self.parent, text='DISPLAY DATA', command=self.display)
self.button.pack()
self.button = tk.Button(self.parent, text='DISPLAY DATA', command=self.display)
self.button.pack()
def load(self):
name = askopenfilename(filetypes=[('CSV', '*.csv',), ('Excel', ('*.xls', '*.xslm', '*.xlsx'))])
if name:
if name.endswith('.csv'):
self.df = pd.read_csv(name)
else:
self.df = pd.read_excel(name)
self.filename = name
display directly
self.text.insert('end', str(self.df.head()) + '\n')
def display(self):
# ask for file if not loaded yet
if self.df is None:
self.load_file()
# display if loaded
if self.df is not None:
self.text.insert('end', self.filename + '\n')
self.text.insert('end', str(self.df.head()) + '\n')
#def script_python(self):
# self.df=self.df.iloc[:, :-1]
#this is not my original script
#def file_save(self):
# savefile = asksaveasfilename(filetypes=(("Excel files", "*.xlsx"),
# ("All files", "*.*") ))
# --- main ---
if __name__ == '__main__':
root = tk.Tk()
top = MyWindow(root)
root.mainloop()
My python script that do analysis on the excel file works, so I just put a very simple python script to make your life easier.
Thank you
I'm new at Tkinter and not used to classes and dictionaries. thanks for your help
I've modified your code, adding a button to run your script and a button to save the data (I've tried to keep the rest as close to your original code as possible):
import tkinter as tk
from tkinter import ttk
from tkinter.filedialog import askopenfilename
from tkinter.filedialog import asksaveasfilename
from tkinter.messagebox import showerror
import pandas as pd
import csv
# --- classes ---
class MyWindow:
def __init__(self, parent):
self.parent = parent
self.filename = None
self.df = None
self.text = tk.Text(self.parent)
self.text.pack()
# load data button
self.load_button = tk.Button(self.parent, text='LOAD DATA', command=self.load)
self.load_button.pack()
# display data button
self.display_button = tk.Button(self.parent, text='DISPLAY DATA', command=self.display)
self.display_button.pack()
# run script button
self.script_button = tk.Button(self.parent, text='RUN SCRIPT', command=self.script_python)
self.script_button.pack()
# save data button
self.save_button = tk.Button(self.parent, text='SAVE DATA', command=self.file_save)
self.save_button.pack()
def load(self):
name = askopenfilename(filetypes=[('CSV', '*.csv',), ('Excel', ('*.xls', '*.xslm', '*.xlsx'))])
if name:
if name.endswith('.csv'):
self.df = pd.read_csv(name)
else:
self.df = pd.read_excel(name)
self.filename = name
# display directly
self.text.insert('end', str(self.df.head()) + '\n')
def display(self):
# ask for file if not loaded yet
if self.df is None:
self.load_file()
# display if loaded
if self.df is not None:
self.text.insert('end', self.filename + '\n')
self.text.insert('end', str(self.df.head()) + '\n')
def script_python(self):
# replace this with the real thing
self.df = self.df.iloc[:, :-1]
def file_save(self):
fname = asksaveasfilename(filetypes=(("Excel files", "*.xlsx"),
("All files", "*.*")))
# note: this will fail unless user ends the fname with ".xlsx"
self.df.to_excel(fname)
# --- main ---
if __name__ == '__main__':
root = tk.Tk()
top = MyWindow(root)
root.mainloop()
I am trying to write a GUI that can display the log file in real time (tail -f log). The new line from the log file can be printed out into the terminal, but it cannot be loaded into the text field (line #). Can any one tell me why it won't put back to the text field?
from Tkinter import *
import os, time
import tkFileDialog
class Controller(object):
def __init__(self, master):
""" Main interface:
master - the top level window
"""
self._master = master
frame1 = Frame(self._master)
label = Label(self._master, text="Select a Log File")
label.pack(side=TOP)
currentLogfile = StringVar(self._master)
LogfileList = [f for f in os.listdir('.') if os.path.isfile(f)]
currentLogfile.set(LogfileList[0])
chooseLog = OptionMenu(self._master, currentLogfile, *LogfileList, command = self.file_open)
chooseLog.config(width = "300")
chooseLog.pack(side=TOP)
self._master.config(menu=chooseLog)
self._Text=Text(frame1, bg = 'black', fg = 'white')
self._Text.pack(side = TOP,fill=BOTH, expand = True,pady=20)
w = Scrollbar(self._Text)
w.pack(side=RIGHT, fill=Y)
frame1.pack(side=TOP, fill=BOTH, padx=5,expand=True)
def file_open(self,filename):
#clear text field
self._Text.delete('1.0', END)
with open(filename,'r') as f:
loglines = follow(f)
for line in loglines:
#print line
self._Text.insert(END,line)
def follow(thefile):
thefile.seek(0,2)
while True:
line = thefile.readline()
if not line:
time.sleep(5)
continue
yield line
if __name__ == "__main__":
root=Tk()
c=Controller(root)
root.title("log")
root.geometry("750x500")
root.mainloop()
How could I use the winsound.PlaySound() function to play with a variable stored instead of a specific sound? I am making a makeshift Music Player and I want to be able to simply play a song that is selected by the user. Here's my current code.
import Tkinter, Tkconstants, tkFileDialog
import winsound
from Tkconstants import *
from tkFileDialog import *
from PIL import Image, ImageTk
class MusicPlayer(Tkinter.Frame):
def __init__(self, root):
Tkinter.Frame.__init__(self, root)
# options for buttons
button_opt = {'fill': Tkconstants.BOTH, 'padx': 5, 'pady': 5}
#options for images
# define image
img = Image.open('musicPlayer.PNG')
bg = ImageTk.PhotoImage(img)
label = Tkinter.Label(image=bg)
label.image = bg
label.pack()
# define buttons
but1 = Tkinter.Button(self, text='Play', command=self.play)
but2 = Tkinter.Button(self, text='Stop', command=self.stop)
but1.grid(sticky="S, W, E", column=1)
but1.grid(sticky="S, W, E", column=1)
# define options for opening or saving a file
self.file_opt = options = {}
options['defaultextension'] = '*.wav'
options['filetypes'] = [('WAV Sound Files', '*.wav')]
options['initialdir'] = 'C:\\'
options['initialfile'] = '.wav'
options['parent'] = root
options['title'] = 'Pick a File'
# This is only available on the Macintosh, and only when Navigation Services are installed.
#options['message'] = 'message'
# if you use the multiple file version of the module functions this option is set automatically.
#options['multiple'] = 1
# defining options for opening a directory
self.dir_opt = options = {}
options['initialdir'] = 'C:\\'
options['mustexist'] = False
options['parent'] = root
options['title'] = 'Pick a Dir'
def askopenfile(self):
return tkFileDialog.askopenfile(mode='r', **self.file_opt)
def askopenfilename(self):
# get filename
filename = tkFileDialog.askopenfilename(**self.file_opt)
# open file on your own
if filename:
return open(filename, 'r')
print filename
def asksaveasfile(self):
return tkFileDialog.asksaveasfile(mode='w', **self.file_opt)
def asksaveasfilename(self):
# get filename
filename = tkFileDialog.asksaveasfilename(**self.file_opt)
# open file on your own
if filename:
return open(filename, 'w')
def askdirectory(self):
return tkFileDialog.askdirectory(**self.dir_opt)
def play(self):
soundfile = self.askopenfilename()
winsound.PlaySound(soundfile, winsound.SND_FILENAME)
def stop(self):
winsound.PlaySound(None, winsound.SND_PURGE)
if __name__=='__main__':
root = Tkinter.Tk()
root.iconbitmap(r'C:\Python27\DLLs\musicPlayer.ico')
MusicPlayer(root).pack()
root.wm_title('Music Player')
root.mainloop()
Things to Note
I am new to the winsound plugin, as well as Python itself, and I am not sure which flag I am supposed to use.
Error I get
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1532, in __call__
return self.func(*args)
File "C:\Users\Brenneman.Josh.19\Downloads\code (2)\MusicPlayer.py", line 88, in play
winsound.PlaySound(soundfile, winsound.SND_FILENAME)
TypeError: must be string or read-only buffer, not file
winsound's PlaySound() needs to be passed a string with the filename and one or more flags. I'd recommend the SND_ASYNC flag, which plays the sound and returns immediately. Use the following:
winsound.PlaySound('C:/Windows/Media/chimes.wav', winsound.SND_ASYNC)
I have this code in python 2.7 using tkinter that creates a Button on a Frame to open a file. There's a Label under it. I'm trying to make it so once the file is opened, the label prints the path, "file1.name" or whatever, on the Label, and if you open a new file it will change that Label again.
Also, I'm betting there's a better way to move data between the functions than I'm using here with global, but that's not worrying me right now.
I have to move the data from the opened files between functions so that I can mix the data and save to a new file. The code is:
from Tkinter import *
import Tkinter
import tkFileDialog
import tkMessageBox
root = Tkinter.Tk()
global rfile1
global rfile2
rfile1 = ""
rfile2 = ""
class Application(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.grid()
self.createWidgets1()
self.createLabels1()
self.createWidgets2()
self.createLabels2()
def createWidgets1(self):
self.oButton = Button(self, text = "open1", command = self.openfile1)
self.oButton.grid()
def createLabels1(self):
self.oLabel = Label(self, text = "whoops")
self.oLabel.grid()
def createWidgets2(self):
self.oButton = Button(self, text = "open2", command= self.openfile2)
self.oButton.grid()
def createLabels2(self):
self.oLabel2 = Label(self, text = "whoops2")
self.oLabel2.grid()
def openfile1(self):
file1 = tkFileDialog.askopenfile(title = "choose a file, *****", parent=root, mode = 'rb')
rfile1 = file1.read()
tkMessageBox.showinfo("oy", rfile1, parent=root)
def openfile2(self):
file2 = tkFileDialog.askopenfile(parent=root, mode='rb')
rfile2 = file2.read()
tkMessageBox.showinfo("hola", rfile2, parent=root)
app = Application()
app.master.title("whiggy whompus")
app.mainloop()
If I understand correctly, you want something like (untested):
def openfile1(self):
file1 = tkFileDialog.askopenfile(title = "choose a file, *****", parent=root, mode = 'rb')
self.oLabel.configure(text=file1.name)
rfile1 = file1.read()
tkMessageBox.showinfo("oy", rfile1, parent=root)
#mgilson has solved your first question. Your second question, about how to pass parameters between functions without using globals :
you might want to look at storing the variables as attributes on your application class :
The syntax self. is an attribute on the current instance (an instance being a particular example of a class - just like your car is a specific example of a class "car").
You can use instance attributes in this example as if they are globals.
from Tkinter import *
import Tkinter
import tkFileDialog
import tkMessageBox
root = Tkinter.Tk()
class Application(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.grid()
self.createWidgets1()
self.createLabels1()
self.createWidgets2()
self.createLabels2()
self.rfile1 = ""
self.rfile2 = ""
def createWidgets1(self):
self.oButton = Button(self, text = "open1", command = self.openfile1)
self.oButton.grid()
def createLabels1(self):
self.oLabel = Label(self, text = "whoops")
self.oLabel.grid()
def createWidgets2(self):
self.oButton = Button(self, text = "open2", command= self.openfile2)
self.oButton.grid()
def createLabels2(self):
self.oLabel2 = Label(self, text = "whoops2")
self.oLabel2.grid()
def openfile1(self):
file1 = tkFileDialog.askopenfile(title = "choose a file, *****", parent=root, mode = 'rb')
self.rfile1 = file1.read()
tkMessageBox.showinfo("oy", self.rfile1, parent=root)
def openfile2(self):
file2 = tkFileDialog.askopenfile(parent=root, mode='rb')
self.rfile2 = file2.read()
tkMessageBox.showinfo("hola", self.rfile2, parent=root)
app = Application()
app.master.title("whiggy whompus")
app.mainloop()