I am writing a Python module which will read and analyze an input file for a specialized software program. I want the user to be able to analyze whichever input file they choose. So far I've tried 2 methods to get the file name:
Method 1:
filename = input('File to be analyzed: ')
Pro: simplest method
Con: difficult for user to type long file path every time
Method 2:
Put a file called path.txt in the same directory as the Python module and the user can store the filename there.
import os
pathtxt_dir = os.path.dirname(os.path.realpath(__file__))
pathtxt_fullpath = os.path.join(pathtxt_dir, 'path.txt')
try:
fo = open(pathtxt_fullpath, 'r')
lines = fo.readlines()
fo.close()
except IOError:
raise Exception('path.txt cannot be opened')
filename = lines[0].rstrip().lstrip() # input file
Pro: Coworkers are familiar with this approach since it is similar to previous programs they have used.
Con: It seems like an unnecessarily complicated way to get user input
Question:
Is there a canonical Python method for getting long and repetitive user inputs, like this filename? Also, is there another useful method that I have not considered?
You can use tkinter to open a GUI for them to select the file. That way they don't have to type it out every time.
import tkinter as tk
from tkinter import filedialog as fd
import os
def getfile(title='Choose files', sformat='.*'):
root = tk.Tk()
root.lift()
# d and f are whatever default directory and filename
try:
f = fd.askopenfilename(parent=root, title=title, filetypes=[('', sformat)], initialdir=d, initialfile=f)
root.withdraw()
return f
except:
# print(title + ': error - no file exists')
return ''
Related
I have a program that makes voice text using .txt ,but os.startfile doesn't let me select the file, hence get the path to it) I will be very grateful for your help!!
Как должно быть.
enter image description here
Как у меня)
enter image description here
import os
import pyttsx3 as pyt
from gtts import gTTS
class DICTOR:
def __init__(self, path):
self.engine = pyt.init()
#voices = self.engine.getProperty('voices')
self.engine.setProperty('voice', 0)
#rate = self.engine.getProperty('rate')
self.engine.setProperty('rate', 150)
with open(path, 'r') as file:
self.file = file.read()
# def speak(self):
# self.engine.say(self.file)
# self.engine.runAndWait()
def save(self, filename):
tss = gTTS(text = self.file, lang='en')
tss.save(filename)
#rate = self.engine.getProperty('rate')
path = os.startfile(filepath = 'D:\Python\Road_map\DICTOR')
DICTOR(path).save('.mp3')
I'm guessing your problem is with the formatting. You should add r to the start. It should be:
path = os.startfile(filepath = r"G:\EEGdatabase\6541455.docx")
the r is needed because \ is considered to be a special character by python. Another option is to escape \ with \\:
path = os.startfile(filepath = 'D:\\Python\\Road_map\\DICTOR')
More info in the docs.
Finally, since you haven't provided your error message, maybe this isn't your problem at all. If this doesn't fix it, add your error log so we know exactly what is going on.
Edit: It seems you have misunderstood the use of os.startfile. This function takes in something you need to "start", and starts it. So if you had said
os.startfile("something.pdf")
Then something.pdf will be opened in your default PDF software. If you instead passed in something like file.html, then this html file will be opened in your default web browser.
So you are now passing in D:\Python\Road_map\DICTOR, which is a folder, and the startfile function simply opens up that folder in Windows Explorer. A full reference for startfile can be found in the docs.
In any case, I don't think you need startfile at all. You need a file selector, which you can get using the Tkinter package. You can then say:
from Tkinter import Tk # from tkinter import Tk for Python 3.x
from tkinter.filedialog import askopenfilename
Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
filename = askopenfilename() # show an "Open" dialog box and return the path to the selected file
print(filename)
path = filename
(Taken from https://stackoverflow.com/a/3579625/3730626)
I am making a game laucnher project, where you can browse through the games and then organise them all at one place.
The issue i am getting is:
To browse i written this code:
def browse():
global name
global app_bro
global data
global f
global g
global list_of
app_bro = filedialog.askopenfilename(title='',filetype = [('Application', '*.exe')])
name = os.path.basename(app_bro)
moment=time.strftime("%Y-%b-%d__%H_%M_%S",time.localtime())
f_name = 'C:/Users/vatsa/Desktop/Launcher/mygames/'+name+ '.txt'
with open(f_name, 'wb') as f:
pickle.dump(name, f)
with open(f_name , 'rb') as f:
list_of = pickle.load(f)
here, this is the part of the code to browse the apps:
app_bro = filedialog.askopenfilename(title='',filetype = [('Application', '*.exe')])
Now, i want to get the file path of the selected file, and i want to use that path to run the exe app when clicked on a button. here is the code:
def open_app():
win_cmd = app_bro
process = subprocess.Popen(win_cmd,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE )
in the win_cmd variable, we are supposed to pass the path of the file to run the application, so i put app_bro variable which earlier used to browse. i am getting the following error:
NameError: name 'app_bro' is not defined
First of all, we need to get rid of the global variable since they aren't really useful in this situation. We can use the return instead in order to have a code way cleaner and usable in multiple files.
Than, you can execute the file using the os module, mostly the script:
os.system(f"start {path}")
The final piece of code is:
import os
import tkinter
from tkinter import filedialog
import time
def browse():
app_bro = filedialog.askopenfilename(title='',filetype = [('Application', '*.exe')])
name = os.path.basename(app_bro)
moment=time.strftime("%Y-%b-%d__%H_%M_%S",time.localtime())
username = os.getenv("UserName")
path = f"C:\\Users\\{username}\\Downloads\\{name}"
os.system(f"start {path}")
return {"app":app_bro, "name":name, "moment":moment, "username":username, "path":path}
browse()
Here you go :)
Epic saves it's shortcuts in a .url file format, I wish to make use of the askopenfilename() function of tkinter to just select the shortcut and then with the code bellow open the directory of the game, but whenever I try such a thing with said function I get a "catastrophic error",is there any way to select it with tkinter.filedialog? or, are there any other functions I could use to achieve the same result?
import os
import tkinter.filedialog as fd
target_url = #Here is where I wish to put a fd.askopenfilename() function, but as I described, this doesn't work#
#Thus far the target_url variable is just an input()#
data = open(target_url, mode='r')
data_read = data.read()
data_index = data_read.index("IconFile=")
exe = data_read[data_index:].replace('IconFile=', '')
replaced = os.path.basename(exe)
open_thing_2 = exe.replace(replaced, '')
os.startfile(open_thing_2)
For easier debugging, this is a example of the contents of such .url file.
[{Number_Array}]
Prop3=19,0
[InternetShortcut]
IDList=
IconIndex=0
WorkingDirectory=C:\Program Files (x86)\Epic Games
URL=com.epicgames.launcher://apps/Jaguar?action=launch&silent=true
IconFile=C:\Program Files\Epic Games\Game_Name\Game_Name.exe
Thank you for your help.
I can not find a way using the the Tkinter tkFileDialog.askopenfilename / Open() method to get a file name of an already opened file. At least on Windows 7 anyway.
Simply need to return the filename selected, but when I select an 'opened' file I get the "This file is in use" popup. Any searches for getting filenames seems to always point back to using FileDialog.
There seems to be the same question but using c# here:
Open File Which is already open in window explorer
Are there any ways not listed that can be used to arrive at this? A file selection popup that doesn't fail on already opened files on Windows 7?
Python 2.7.11
Windows 7_64
Selection dialog:
opts = {}
opts['title'] = 'Select file.'
filename = tkFileDialog.Open(**opts).show()
or
filename = tkFileDialog.askopenfilename(**opts)
Which are the same as askopenfilename calls Open().show() which in turn is calling command = "tk_getOpenFile".
Searching tk_getOpenFile shows nothing to override this behavior.
Any pointers here would be much appreciated.
Update:
So as to not reiterate everything that's been gone over here's the break down of the Tkinter 8.5 FileDialog.
def askopenfile(mode = "r", **options):
"Ask for a filename to open, and returned the opened file"
filename = Open(**options).show()
if filename:
return open(filename, mode)
return None
def askopenfilename(**options):
"Ask for a filename to open"
return Open(**options).show()
Both call the Open class but askopenfile follows up with an open(file), here:
class Open(_Dialog):
"Ask for a filename to open"
command = "tk_getOpenFile"
def _fixresult(self, widget, result):
if isinstance(result, tuple):
# multiple results:
result = tuple([getattr(r, "string", r) for r in result])
if result:
import os
path, file = os.path.split(result[0])
self.options["initialdir"] = path
# don't set initialfile or filename, as we have multiple of these
return result
if not widget.tk.wantobjects() and "multiple" in self.options:
# Need to split result explicitly
return self._fixresult(widget, widget.tk.splitlist(result))
return _Dialog._fixresult(self, widget, result)
UPDATE2(answerish):
Seems the windows trc/tk tk_getOpenFile ultimately calls
OPENFILENAME ofn;
which apparently can not, at times, return a filename if the file is in use.
Yet to find the reason why but regardless.
In my case, needing to reference a running QuickBooks file, it will not work using askopenfilename().
Again the link above references someone having the same issue but using c# .
I am writing a program in python on Ubuntu. In that program I am struggling to select a file using the command askopenfilename on a remote network connected RaspberryPi.
Can anybody guide me on how to select a file from the remote machine using askopenfilename command or something similar?
from Tkinter import *
from tkFileDialog import askopenfilename
import paramiko
if __name__ == '__main__':
root = Tk()
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('192.168.2.34', username='pi', password='raspberry')
name1= askopenfilename(title = "Select File For Removal", filetypes = [("Video Files","*.h264")])
stdin, stdout, stderr = client.exec_command('ls -l')
for line in stdout:
print '... ' + line.strip('\n')
client.close()
Haha, hello again!
It's not possible to use a tkinter's file dialogs to list (or select) files on remote machine. You would need to mount the remote machine's drive using, for example, SSHFS (as mentioned in the question's comment), or use a custom tkinter dialog which displays the remote files list (that is in the stdout variable) and lets you choose the one.
You can write a dialog window yourself, here's a quick demo:
from Tkinter import *
def double_clicked(event):
""" This function will be called when a user double-clicks on a list element.
It will print the filename of the selected file. """
file_id = event.widget.curselection() # get an index of the selected element
filename = event.widget.get(file_id[0]) # get the content of the first selected element
print filename
if __name__ == '__main__':
root = Tk()
files = ['file1.h264', 'file2.txt', 'file3.csv']
# create a listbox
listbox = Listbox(root)
listbox.pack()
# fill the listbox with the file list
for file in files:
listbox.insert(END, file)
# make it so when you double-click on the list's element, the double_clicked function runs (see above)
listbox.bind("<Double-Button-1>", double_clicked)
# run the tkinter window
root.mainloop()
The easiest solution without a tkinter is - you could make the user type the filename using the raw_input() function.
Kind of like that:
filename = raw_input('Enter filename to delete: ')
client.exec_command('rm {0}'.format(filename))
So the user would have to enter the filename that is to be deleted; then that filename gets passed directly to the rm command.
It's not really a safe approach - you should definitely escape the user's input. Imagine what if the user types '-rf /*' as a filename. Nothing good, even if you're not connected as a root.
But while you're learning and keeping the script to yourself I guess it's alright.