I tried to do the save dialog, where I should choose a file extension, when the data will be saved to.
simple code in python:
def onSave(self, e):
dlg = wx.FileDialog(self, "Choose file", self.dir, "", "*.txt|*.docx", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if dlg.ShowModal() == wx.ID_OK:
self.file = dlg.GetFilename()
self.dir = dlg.GetDirectory()
#do something
dlg.Destroy()
Only .txt file is shown in file type selector. WHat is it possible to do more than one file type available to choose?
I'm using python 3.8 and the newest version of WxWidgets on Archlinux
Related
I'm writing a UI for a python app with wxPython. I've handled a few of the OnX functions but I need help with OnNew and OnSave/SaveAs
Here is my Save and SaveAs code:
def OnSave(self, event):
self.dirname = ""
saveFileDialog = wx.FileDialog(self, "Save Operation File", self.dirname, "",
"Operation Files (*.fwr)|*.fwr|All Files (*.*)|*.*", wx.SAVE|wx.OVERWRITE_PROMPT)
if saveFileDialog.ShowModal() == wx.ID_OK:
contents = self.control.GetValue()
self.filename = saveFileDialog.GetFilename()
self.dirname = saveFileDialog.GetDirectory()
filehandle = open(os.path.join(self.dirname, self.filename), 'w')
filehandle.write(contents)
filehandle.close()
else:
sys.exit(1)
saveFileDialog.Destroy()
def OnSaveAs(self, event):
self.dirname = "";
saveAsFileDialog = wx.FileDialog(self, "Save Operation File As", self.dirname, "",
"Operation Files (*.fwr)|*.fwr|All Files (*.*)|*.*",
wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if saveAsFileDialog.ShowModal() == wx.ID_OK:
contents = self.control.GetValue()
self.filename = saveFileDialog.GetFilename()
self.dirname = saveFileDialog.GetDirectory()
filehandle = open(os.path.join(self.dirname, self.filename), 'w')
filehandle.write(contents)
filehandle.close()
else:
sys.exit(1)
saveFileDialog.Destroy()
# save current contents in the file
# use wxPython output streams
#output_stream = wx.FileOutputStream(saveFileDialog.GetPath())
#if not output_stream.IsOk():
# wx.LogError("Cannot save contents of Operations File '%s'" % saveFileDialog.GetPath())
# return
the commented part at the bottom is another way I found to do it, is using the input and output streams more correct than the way it currently is? Also heres my other question, I got OnNew Working, here is the code:
def OnNew(self, event):
homedir = os.environ['HOME']
if not os.path.exists(homedir):
if getpass.getuser():
homedir = "C:/Users/" + getpass.getuser() + "/"
else:
homedir = "C:/"
newFileDialog = wx.FileDialog(self, "New Operation File", homedir, "",
"Operation Files (*.fwr)|*.fwr|All Files|(*.*)|*.*", wx.FD_CREATE|wx.OVERWRITE_PROMPT)
Everything is great but the OnOpen Method opens an open file dialog, I want a create file dialog (would this be the same as save? Can someone give me an example OnOpen method, and give me some insight into my OnSave and OnSaveAs methods? As you can see there are three aproaches, one in OnSaveAs, one in OnSave, and one commented out at the bottom of OnSaveAs(). As well as many more I didn't write down here. My main question though is how to get the filedialog for new to be a save dialog where you create a file, rather than an open dialog.
Thanks a ton.
SUMMARY:
1) How do you bring up a FileDialog that allows creation of blank files. I assum it will be similar to save, but hwatever ID flags I pass it always gives me an Open button
2) And as for save methods, is it better to do what I showed in the code, or use streams like the commented out section in SaveAs?.
To get the Save dialog, you need to pass the wx.SAVE style flag to your FileDialog object: style=wx.SAVE. You can read more about the save flag here or here.
Here's some example code that worked for me on Xubuntu 14.04 with wxPython 2.8.12.1 and Python 2.7:
import os
import wx
wildcard = "Python source (*.py)|*.py|" \
"All files (*.*)|*.*"
########################################################################
class MyForm(wx.Frame):
#----------------------------------------------------------------------
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY,
"File and Folder Dialogs Tutorial")
panel = wx.Panel(self, wx.ID_ANY)
self.currentDirectory = os.getcwd()
saveFileDlgBtn = wx.Button(panel, label="Show SAVE FileDialog")
saveFileDlgBtn.Bind(wx.EVT_BUTTON, self.onSaveFile)
# put the buttons in a sizer
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(saveFileDlgBtn, 0, wx.ALL|wx.CENTER, 5)
panel.SetSizer(sizer)
#----------------------------------------------------------------------
def onSaveFile(self, event):
"""
Create and show the Save FileDialog
"""
dlg = wx.FileDialog(
self, message="Save file as ...",
defaultDir=self.currentDirectory,
defaultFile="", wildcard=wildcard, style=wx.FD_SAVE
)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
print "You chose the following filename: %s" % path
dlg.Destroy()
#----------------------------------------------------------------------
# Run the program
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm()
frame.Show()
app.MainLoop()
I don't see anything wrong with your saving approach. In most cases, it's better to use Python's low level operators instead of using wxPython's. I would use Python's with operator though as that follows the newer idiom better:
with open(os.path.join(self.dirname, self.filename), 'w') as filehandle:
filehandle.write(contents)
I'm using pyqt and I just made a Qfiledialog to save a PDF that my program produced, like this:
QtGui.QFileDialog.getSaveFileName(self, "Save file", "", ".pdf")
But the file must be saved at "P:\", in any folder, but have to be "P:".
How can I do that?
You need directoryEntered and fileSelected signals instead of modal getSaveFileName. Some pseudo code:
self.dialog = QtGui.QFileDialog()
self.dialog.directoryEntered.connect(self.checkDir)
self.dialog.fileSelected.connect(self.saveFile)
self.dialog.setAcceptMode(QFileDialog.AcceptSave)
self.dialog.setFileMode(QFileDialog.AnyFile)
self.dialog.setDirectory("P:")
self.dialog.show()
....
def checkDir(self, directory):
if not (directory.startsWith("P:")):
self.dialog.setDirectory("P:")
def saveFile(self, fileName):
directory = QtCore.QFileInfo(fileName).canonicalPath()
I am trying to build an example from book "wxPython in Action" page 270.
Here is the code:
import wx
import os
if __name__ == "__main__":
app = wx.App()
wildcard = "Python source(*.py)|*.py|"\"Compiled Python(*.pyc)|*.pyc|"\"All files(*.*)|*.*"
dlg = wx.FileDialog(None, "Choose input file", os.getcwd(), "", wildcard, wx.OPEN)
if dlg.ShowModal() == wx.ID_OK:
print dlg.GetPath()
dlg.Destroy()
I saved it as .py source file, and run it in IDLE. But it gives me following error:
There's an error in your program: unexpected character after line
comtinuation character
May I know why this example doesn't work? Thanks.
try change
wildcard = "Python source(*.py)|*.py|"\"Compiled Python(*.pyc)|*.pyc|"\"All files(*.*)|*.*"
to
wildcard = "Python source(*.py)|*.py|Compiled Python(*.pyc)|*.pyc|All files(*.*)|*.*"
I am learning to use wxPython to build a dialogue based program.
I tried following code (simply copied from wxPython Demo):
import wx
#---------------------------------------------------------------------------
class TestPanel(wx.Panel):
def __init__(self, parent, log):
self.log = log
wx.Panel.__init__(self, parent, -1)
b = wx.Button(self, -1, "Create and Show a DirDialog", (50,50))
self.Bind(wx.EVT_BUTTON, self.OnButton, b)
def OnButton(self, evt):
# In this case we include a "New directory" button.
dlg = wx.DirDialog(self, "Choose a directory:",
style=wx.DD_DEFAULT_STYLE
#| wx.DD_DIR_MUST_EXIST
#| wx.DD_CHANGE_DIR
)
# If the user selects OK, then we process the dialog's data.
# This is done by getting the path data from the dialog - BEFORE
# we destroy it.
if dlg.ShowModal() == wx.ID_OK:
self.log.WriteText('You selected: %s\n' % dlg.GetPath())
# Only destroy a dialog after you're done with it.
dlg.Destroy()
#---------------------------------------------------------------------------
def runTest(frame, nb, log):
win = TestPanel(nb, log)
return win
#---------------------------------------------------------------------------
overview = """\
This class represents the directory chooser dialog. It is used when all you
need from the user is the name of a directory. Data is retrieved via utility
methods; see the <code>DirDialog</code> documentation for specifics.
"""
if __name__ == '__main__':
import sys,os
import run
run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
I ran above code both in Python IDLE and Apatana Studio 3. Here is what I got.
In Python IDLE, I've got:
IDLE Subprocess: no IP port passed in sys.argv.
And in Apatana Studio 3, I've got:
Traceback (most recent call last):
File "C:\Users\User\My Documents\Aptana Studio 3 Workspace\Test Dialogue\main.py", line 61, in
import run ImportError: No module named run
May I know what am I wrong? Thanks a lot. :)
The ImportError is the Python interpreter (the program that runs your Python code) letting you know it cannot find the module (.py file) you are trying to import. Specifically, the error is saying it cannot find the module "run" which you have asked it to import on line 61.
When you do an import in Python, the interpreter searches a bunch of places for the module. One of those is the current directory, and the rest are standard places like where Python libraries are installed. This page has some info about it: http://docs.python.org/2/tutorial/modules.html#the-module-search-path. You'll actually get the same ImportError if you run the program from the command line. It's a Python error, not an Apatana Studio 3 error.
So if you copy "run.py" into the directory with your Python file, the Python interpreter will be able to easily find it when you asks it to import. Another way is to leave the run.py module where it is and change the sys.path at runtime, or add the module location to the PYTHONPATH variable (see link above for more info).
The run.py module isn't needed for what you are trying to achieve though. Here's an example of your code without the run.py module being imported. I'll warn that I'm new to wxPython myself so there may be better ways to do it ;-)
import wx
# This Log class is copied from the run module
class Log(object):
def WriteText(self, text):
if text[-1:] == '\n':
text = text[:-1]
wx.LogMessage(text)
write = WriteText
class TestPanel(wx.Panel):
def __init__(self, parent, log):
self.log = Log()
wx.Panel.__init__(self, parent, -1)
b = wx.Button(self, -1, "Create and Show a DirDialog", (50,50))
self.Bind(wx.EVT_BUTTON, self.OnButton, b)
def OnButton(self, evt):
# In this case we include a "New directory" button.
dlg = wx.DirDialog(self, "Choose a directory:",
style=wx.DD_DEFAULT_STYLE
#| wx.DD_DIR_MUST_EXIST
#| wx.DD_CHANGE_DIR
)
# If the user selects OK, then we process the dialog's data.
# This is done by getting the path data from the dialog - BEFORE
# we destroy it.
if dlg.ShowModal() == wx.ID_OK:
self.log.WriteText('You selected: %s\n' % dlg.GetPath())
# Only destroy a dialog after you're done with it.
dlg.Destroy()
class Frame ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__(self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size(300, 150))
panel = TestPanel(self, -1)
class App(wx.App):
def OnInit(self):
self.frame = Frame(parent=None)
self.frame.Show()
self.SetTopWindow(self.frame)
return True
if __name__ == '__main__':
app = App()
app.MainLoop()
I'm not sure what's happening with the error in IDLE though. That's weird!
I want the open dialog to filter files by *.spectrum or not filter it (*.* all files).
I also want the save dialog to suggest a .spectrum extension when saving. The common, new file.ext where the new file is highlighted for us to overwrite.
I have set the wildcard = "*.spectrum" for both options, but please give me a more complete solution.
I've written a couple articles on this subject:
wxPython: Showing 2 Filetypes in wx.FileDialog
The Dialogs of wxPython
Basically what you want for the open and save dialogs is something like this:
wildcard = "Python source (*.spectrum)|*.spectrum|" \
"All files (*.*)|*.*"
Then in the code, you'd do something like this:
def onOpenFile(self, event):
"""
Create and show the Open FileDialog
"""
dlg = wx.FileDialog(
self, message="Choose a file",
defaultDir=self.currentDirectory,
defaultFile="",
wildcard=wildcard,
style=wx.OPEN | wx.MULTIPLE | wx.CHANGE_DIR
)
if dlg.ShowModal() == wx.ID_OK:
paths = dlg.GetPaths()
print "You chose the following file(s):"
for path in paths:
print path
dlg.Destroy()
#----------------------------------------------------------------------
def onSaveFile(self, event):
"""
Create and show the Save FileDialog
"""
dlg = wx.FileDialog(
self, message="Save file as ...",
defaultDir=self.currentDirectory,
defaultFile="", wildcard=wildcard, style=wx.SAVE
)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
print "You chose the following filename: %s" % path
dlg.Destroy()
Note: Code taken directly from my blog and only modified slightly.