Passing an open file from one function to another - python

I'm a python beginner so bear with me. I have written some code on a GUI that allows users to select a file using one button (browse_inputfile), it then displays the file path and then the user can click another button to run a conversion on that file (run_conversion).
However to do this I've had to define a global variable to enable the open file to be passed from one function to another. Is there a better way to do this? I tried passing the path and actually opening it in the second function but this produced "file not found" errors I think due to the "\" used in the string path.
This is the code I have:
def browse_inputfile(self):
global inputfile
inputfile = open(QtGui.QFileDialog.getOpenFileName(self, "Open Data File", "", "txt files (*.txt)"),'r+')`
Then there's some code to display the path using "inputfile.name".
The second function is like this:
def run_conversion(self):
global inputfile
if inputfile: # if user didn't pick a file don't continue
#do stuff
inputfile.close()
I know using global variables is not good practise, so how can I pass the open file from one function to another and have it so that the user clicks the second button before the "stuff" is run on the file?
I want them to be able to check it's the right file before doing the "stuff" on it.
Thanks

Use inputfile as field of the class, in this way there is no need to pass the file as a parameter or to use a global.
class MyClass:
def browse_inputfile(self):
self.inputfile = open(QtGui.QFileDialog.getOpenFileName(self, "Open Data File", "", "txt files (*.txt)"),'r+')`
# you code for display the path
def run_conversion(self):
if self.inputfile: # if user didn't pick a file don't continue
#do stuff
self.inputfile.close()

Your current method risks inputfile not being closed on exit. I would do something like this:
file_path = None
def browse_inputfile(self):
return QtGui.QFileDialog.getOpenFileName(self, 'Openfile', '/home')
def run_conversion(self, path):
if path: # if user didn't pick a file don't continue
with open(path) as f:
#do stuff
If you want to manipulate file names robustly, use the functions in the os.path module https://docs.python.org/2/library/os.path.html.

Related

How to use askfilename() or similar to get the name of a .url file with Python

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.

Tkinter FileDialog.askopenfilename failing on already open files

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# .

Get name of file for command line

I am hoping someone may be able to teach me how to get the name of a file and then make it a part of a string. I want to be able to save a file and then use the name of the file to execute a command line. Here is what I have so far.
def save(self):
filename = QtGui.QFileDialog.getSaveFileName(self, "Save file", "", ".inp")
if filename == "":
pass
else:
nfile = open(filename, 'w')
self.cursor.movePosition(self.cursor.Start, self.cursor.MoveAnchor)
self.cursor.movePosition(self.cursor.End, self.cursor.KeepAnchor)
text = self.cursor.selection()
text1 = text.toPlainText()
nfile.write(text1)
nfile.close()
I want to take the name of the file I just created and insert it in this line:
import os
os.system("rungms file_name.inp 13-64 1 0 file_name.out")
Here's a solution using QT convenient QFileInfo. It will work with a file name, or with a path.
filename="myFileName.something"
fileInfo=QtCore.QFileInfo(filename)
name=fileInfo.baseName()
myCommand="rungms %s.inp 13-64 1 0 %s.out"%(name,name)
Or without QT:
filename="myFileName.something"
name=filename.split(".")[0]
myCommand="rungms %s.inp 13-64 1 0 %s.out"%(name,name)
NB: With "filename.foo1.foo2", the first method will give you "filename.foo1" and the second method "filename"
Use os.path.splitext
from os import path
print(path.splitext("filename.inp")[0]+".out")
This works even if you have more than one period in the filename, and also doesn't count the period at the beginning of the filename used to make hidden files.

Save Dialog only appear once?

I am currently making a desktop widget and what I want to do is create a file in which a user can edit and then save. However, if you guys are familiar with Microsoft word or any other text editors, I want it so that after you hit File -> save, a save dialog appears in which you can choose where to save the file and the file's name. However, after the first time, if the file name stays the same, the save dialog will not come up--rather it will just automatically save over what was previously written. This is what I want to implement but I am having trouble trying to do this. Following is my method for saving files using the save dialog but I am unsure on how to save without having the save dialog pop up.
def saveFile(self):
filename = QtGui.QFileDialog.getSaveFileName(None, 'Save File', os.path.expanduser("~/Desktop/Calendar Data/"+self.dateString), ".txt")
f = open(filename, 'w')
filedata = self.text.toPlainText()
f.write(filedata)
f.close()
Anyone have any idea how to do this? If so that would be great! Thanks for helping.
You should make filename an instance attribute, so you can just check if it was already set:
class Spam:
...
def __init__(self):
self.filename = None
def saveFile(self):
if not self.filename:
self.filename = QtGui.QFileDialog.getSaveFileName(...)
# here you should check if the dialog wasn't cancelled
with open(filename, 'w') as f:
f.write(self.text.toPlainText())
...

File management

I am working on python and biopython right now. I have a file upload form and whatever file is uploaded suppose(abc.fasta) then i want to pass same name in execute (abc.fasta) function parameter and display function parameter (abc.aln). Right now i am changing file name manually, but i want to have it automatically.
Workflow goes like this.
----If submit is not true then display only header and form part
--- if submit is true then call execute() and get file name from form input
--- Then displaying result file name is same as executed file name but only change in extension
My raw code is here -- http://pastebin.com/FPUgZSSe
Any suggestions, changes and algorithm is appreciated
Thanks
You need to read the uploaded file out of the cgi.FieldStorage() and save it onto the server. Ususally a temp directory (/tmp on Linux) is used for this. You should remove these files after processing or on some schedule to clean up the drive.
def main():
import cgi
import cgitb; cgitb.enable()
f1 = cgi.FieldStorage()
if "dfile" in f1:
fileitem = f1["dfile"]
pathtoTmpFile = os.path.join("path/to/temp/directory", fileitem.filename)
fout = file(pathtoTmpFile, 'wb')
while 1:
chunk = fileitem.file.read(100000)
if not chunk: break
fout.write (chunk)
fout.close()
execute(pathtoTmpFile)
os.remove(pathtoTmpFile)
else:
header()
form()
This modified the execute to take the path to the newly saved file.
cline = ClustalwCommandline("clustalw", infile=pathToFile)
For the result file, you could also stream it back so the user gets a "Save as..." dialog. That might be a little more usable than displaying it in HTML.

Categories

Resources