Issue
I'm writing a new application.
I used to work with python 2.x and wxPython some years ago, now I got Python 3.7.0 and wxPythonPhoenix 4.0.4 msw (alas).
When I try to use wx.FileDialog with ShowModal, the program freezes.
I did not find any previous question about this. I used (and reduced for the MWE) code from wxWiki like this.
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, ID, title):
wx.Frame.__init__(self, parent, ID, title, size=(400, 200))
fileMenu = wx.Menu()
openItem = fileMenu.Append(-1, "&Open...\tCtrl-O", "Open a new recipe")
menuBar = wx.MenuBar()
menuBar.Append(fileMenu, "&File")
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.OnOpen, openItem)
def OnOpen(self, event):
# otherwise ask the user what new file to open
with wx.FileDialog(self, "Open XYZ file", wildcard="XYZ files (*.xyz)|*.xyz",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
if fileDialog.ShowModal() == wx.ID_CANCEL:
return # the user changed their mind
#you'll never get here
app = wx.App()
frame = MyFrame(None, -1, "test")
frame.Show()
app.MainLoop()
I really don't get it, moreover the code actually worked for a couple of times.
Solution
I started from the minimal working example I copied from the wxpython wiki.
Then I reduced it to your minimal working example. I think the problem might be the -1
value of the id of the fileMenu.Append(-1, …
.
Smallest Minimal Working Example (MWE):
import wx
app = wx.App()
with wx.FileDialog(None, "Open XYZ file", wildcard="XYZ files (*.xyz)|*.xyz",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
if fileDialog.ShowModal() == wx.ID_CANCEL:
print("the user changed their mind")
else:
# Proceed loading the file chosen by the user
pathname = fileDialog.GetPath()
try:
with open(pathname, 'r') as file:
print(file.read())
except IOError:
wx.LogError("Cannot open file '%s'." % newfile)
Based on your code, works perfectly (always):
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, ID, title):
wx.Frame.__init__(self, parent, ID, title, size=(400, 200))
fileMenu = wx.Menu()
openItem = fileMenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
menuBar = wx.MenuBar()
menuBar.Append(fileMenu, "&File")
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.OnOpen, openItem)
def OnOpen(self, event):
# otherwise ask the user what new file to open
with wx.FileDialog(self, "Open XYZ file", wildcard="XYZ files (*.xyz)|*.xyz",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
if fileDialog.ShowModal() == wx.ID_CANCEL:
return # the user changed their mind
# Proceed loading the file chosen by the user
pathname = fileDialog.GetPath()
try:
with open(pathname, 'r') as file:
#self.doLoadDataOrWhatever(file)
print(file.read()) # see, it works!
except IOError:
wx.LogError("Cannot open file '%s'." % newfile)
app = wx.App()
frame = MyFrame(None, wx.ID_ANY, "test")
frame.Show()
app.MainLoop()
More beautiful and with some explanations:
import wx
class MainWindow(wx.Frame):
def __init__(self, parent, title):
# A "-1" in the size parameter instructs wxWidgets to use the default size.
# In this case, we select 200px width and the default height.
wx.Frame.__init__(self, parent, title=title, size=(200,-1))
# Setting up the menu.
filemenu= wx.Menu()
menuOpen = filemenu.Append(wx.ID_OPEN, "&Open"," Open a file to edit")
# Creating the menubar.
menuBar = wx.MenuBar()
menuBar.Append(filemenu,"&File") # Adding the "filemenu" to the MenuBar
self.SetMenuBar(menuBar) # Adding the MenuBar to the Frame content.
# Events.
self.Bind(wx.EVT_MENU, self.OnOpen, menuOpen)
self.Show()
def OnOpen(self,e):
""" Open a file"""
with wx.FileDialog(self, "Open XYZ file", wildcard="XYZ files (*.xyz)|*.xyz",
style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
if fileDialog.ShowModal() == wx.ID_CANCEL:
return # the user changed their mind
# Proceed loading the file chosen by the user
pathname = fileDialog.GetPath()
try:
with open(pathname, 'r') as file:
#self.doLoadDataOrWhatever(file)
print(file.read())
except IOError:
wx.LogError("Cannot open file '%s'." % newfile)
app = wx.App(False)
frame = MainWindow(None, "test")
app.MainLoop()
See also
More GUI options for file dialogs: JFileChooser for Python?
Answered By - erik
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.