Save Dialog only appear once? - python

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())
...

Related

Create New file using File Dialog

How can I create a new file using file dialog with pyqt5?
This is my code so far, it prints out the correct path after I create the new file but it doesn't actually create it
def newFile(self):
name = QtWidgets.QFileDialog.getSaveFileName()
print(name)
The QFileDialog::getSaveFileName() function does not create or save a file as indicated in the docs:
This is a convenience static function that will return a file name selected by the user. The file does not have to exist.
(emphasis mine)
Actually a dialog is created that allows the user to establish the name of a file that the developer must take as a reference to save the information they want, so what you should do is verify the filename is not empty and use it to create the file:
filename, _ = QtWidgets.QFileDialog.getSaveFileName()
if filename:
with open(filename, "w") as f:
# write contents
def newFile(self):
name = QtGui.QFileDialog.getSaveFileName(self, 'Save File')
file = open(name,'w')
text = ""
file.write(text)
file.close()

Saving a Entry Tkinter box to a text file

I have created a Entry box:
I have created a text file:
save_file.close()
However the data being entered is not saving to the text file. This is being saved:
Accounts
<bound method Entry.get of <tkinter.Entry object .!entry>><bound method Entry.get of <tkinter.Entry object .!entry2>>
Any idea on how to fix this?
You need to call the get method.
Change
save_file.write(str(username_input_box.get))
to
save_file.write(str(username_input_box.get()))
As you are having trouble, I have written out a very basic version of your program which I have tested and it works. It writes the "Accounts" text to the file and when the button is pressed, it writes the content of the entry field to the file too. If you code still isn't working, perhaps you'll need to post a more complete and executable example of your code
from tkinter import *
def creating_text_file():
save_file = open("Accounts.txt", "a")
title = "Accounts"
line = "\n"
save_file.write(title)
save_file.write(line)
save_file.close()
def apending_to_text_file():
save_file = open("Accounts.txt", "a")
save_file.write(str(username_input_box.get()))
save_file.write("\n")
save_file.close()
root = Tk()
username_input_box = Entry(root, width=30)
username_input_box.grid()
btn = Button(root,text="Press Me",command=apending_to_text_file)
btn.grid()
creating_text_file()
root.mainloop()
As an improvement, I'd use the context managers to open/close your file. They look like this
with open("Accounts.txt", "a") as save_file:
save_file.write("Some random text")
#No need to close the file as the context manager does this for you

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

Passing an open file from one function to another

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.

wxPython FileOutputStream error

I'm trying to learn wxPython/python and I want to save text in a file. I found this example
def OnSaveAs(self, e):
saveFileDialog = wx.FileDialog(self, "SAVE txt file", "", "", "Textdocument (*.txt)|*.txt", wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if saveFileDialog.ShowModal() == wx.ID_CANCEL:
return # User canceled
# save the current contents in the file
# this can be done with e.g. wxPython output streams:
output_stream = wx.FileOutputStream(saveFileDialog.GetPath())
#My question: Insert what to write to output_stream here?
if not out_stream.IsOk():
wx.LogError("Cannot save current contents in file '%s'."%saveFileDialog.GetPath())
return
I get the error
in OnSaveAs output_stream = wx.FileOutputStream(saveFileDialog.GetPath()) AttributeError 'module' object has no attribute 'FileOutputStream'
Shouldnt output_stream contain the path to the file i want to save. And then I write to output_stream to save text in the file?
Thanks in advance!
Just use the Python functions to open and write content to the file. Something like this:
output = open(saveFileDialog.GetPath(), 'w')
ouput.write(stuff)
ouput.close()
In almost all cases wxPython only wraps the wxWidgets classes and functions which do not already have an equivallent in Python, and the AttributeError is telling you that there is no wx.FileOutputStream class available.

Categories

Resources