At first glance, it seems like it should work. I would suggest trying to produce a complete runnable example that exhibits the problem. That will either help you spot the problem or help us help you.
Well, I don’t see anything menu related in your last post.
When you call self.Bind(wx.EVT_MENU, is self the frame with the menu? Events will not propagate from one frame to another.
Some of your code seems to be generated by wxGlade. This should not create invalid menu bindings. If it does, please submit a ticket at the bug tracker (*).
When you define a menu item in wxGlade with the handler ‘OnFileOpen’, a method stub should be created for the containing frame. For more complex things, you may use a lambda function.
P.S.: I think wxGlade does not yet support lambda handlers for events.
That’s a very good question. Self, I think, refers to the frame in which the menu resides.
You’re right, the original post was generated by WXGlade. The second post was my stripped down code containing a frame with a button which should have run OnFileOpen,
Thanks,
OK, so perhaps I’m misunderstanding.
So here’s the question in a more succinct form:
What is the best way to invoke my OnFileOpen code.
There’s another button in this program which invokes another dialog outside the frame, i.e. hide the frame, show the dialog, and depending on the response show the refreshed frame. So the answer to this question will be quite important,
Thanks,
David.
Don’t hide the frame. That’s very non-standard.
Just open the dialog as modal dialog. This will prevent events and refreshes for the frame anyway.
Depending on the user choice, update your frame.
Dietmar,
Many thanks for your time on changing this, and providing a clear example of how this should be done.
Now I’ve found some questions on which I can do research independently. There are various tutorials out there on event handling, and I’m intending to read them so that my understanding will be clearer,
Many thanks,
David.
def OnTreeAddNode(self, event): # wxGlade: MyFrame.<event_handler>
with MyDialog(self) as dlg:
dlg.text_ctrl_1.SetValue("")
# show as modal dialog
if dlg.ShowModal() == wx.ID_OK:
leaf=dlg.text_ctrl_1.GetValue()
AddToTree(self,leaf)
Missing something very important here,
Thanks,
David.
Success! of a sort. Code now works, but when activating OK or Cancel buttons, nothing happens, i.e. I don’t go back to the original form.
Do I need to associate an event handler to the OK or Cancel buttons in the dialog?
Thanks,
David.
Hi! I’ve tried to glance an eye to your code, I don’t know exactly your target, at least, I’ve succeded to bind a buttonEvent as you wanted. but for that I’ve modified a litle bit your code.
import wx
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
wx.Frame.__init__(self, *args, **kwds)
self.contentNotSaved = True
self.SetSize((400, 300))
self.SetTitle("OpenButton")
self.panel_1 = wx.Panel(self, wx.ID_ANY)
sizer_1 = wx.BoxSizer(wx.VERTICAL)
self.button_1 = wx.Button(self.panel_1, wx.ID_ANY, "Open")
self.button_1.Bind(wx.EVT_BUTTON, self.OnFileOpen)
sizer_1.Add(self.button_1, 0, 0, 0)
self.panel_1.SetSizer(sizer_1)
self.Layout()
def OnFileOpen(self, event):
if self.contentNotSaved:
msg = wx.MessageDialog(self, "Current content has not been saved! Proceed?", "Please confirm",
style = wx.YES_NO | wx.ICON_WARNING | wx.NO_DEFAULT)
response = msg.ShowModal()
if response == wx.ID_YES:
file_path = wx.FileDialog(self)
if file_path.ShowModal()== wx.ID_OK :
print("Fullpath :",file_path.GetPath())
print("filename :",file_path.GetFilename())
print("folder path :",file_path.GetDirectory())
file_path.Destroy()
else:
return
# with wx.FileDialog(self.Myframe, "Open MXP file", wildcard="MXP files (*.MXP)|*.mxp",
# style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:
# if fileDialog.ShowModal() == wx.ID_CANCEL:
# return
# pathname = fileDialog.GetPath()
# try:
# with open(pathname, 'r') as file:
# self.LoadTree(file)
# except IOError:
# wx.LogError("Cannot open file '%s'." % file)
# end wxGlade
# end of class MyFrame
# class MyApp(wx.App):
# def OnInit(self):
# self.frame = MyFrame(None, wx.ID_ANY, "")
# self.SetTopWindow(self.frame)
# self.frame.Show()
# return True
# end of class MyApp
if __name__ == "__main__":
app = wx.App()
frame = MyFrame(None, wx.ID_ANY, "")
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()
Well! I hope it will help you.
An advice! you’d better lean how to make GUI with wx.python only. at the biginnig it’s dificult, but once you spend more time on it, yo’ll see that everything is now easy.
I’m rapidly coming to the conclusion that it would be best to generate code myself in the first instance. I find WXGlade extremely useful, but by learning the correct way to do this, it’ll give me a better understanding when things go wrong,
I’m currently extending wxGlade with some options for some windows and widgets. E.g. when adding a Dialog, there will be an option to add OK and Cancel buttons automatically.