I’m learning Python and WxPython. So far, I’m following the examples in AnotherTutorial, which is mainly wxPython related.
I’m trying to understand the following code:
import wx
class MyMenu(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, wx.DefaultPosition, wx.Size(380, 250))
menubar = wx.MenuBar()
file = wx.Menu()
edit = wx.Menu()
help = wx.Menu()
file.Append(101, '&Open', 'Open a new document')
file.Append(102, '&Save', 'Save the document')
file.AppendSeparator()
quit = wx.MenuItem(file, 105, '&Quit\tCtrl+Q', 'Quit the Application')
quit.SetBitmap(wx.Image('stock_exit-16.png',wx.BITMAP_TYPE_PNG).ConvertToBitmap())
file.AppendItem(quit)
edit.Append(201, 'check item1', '', wx.ITEM_CHECK)
edit.Append(202, 'check item2', kind=wx.ITEM_CHECK)
submenu = wx.Menu()
submenu.Append(301, 'radio item1', kind=wx.ITEM_RADIO)
submenu.Append(302, 'radio item2', kind=wx.ITEM_RADIO)
submenu.Append(303, 'radio item3', kind=wx.ITEM_RADIO)
edit.AppendMenu(203, 'submenu', submenu)
menubar.Append(file, '&File')
menubar.Append(edit, '&Edit')
menubar.Append(help, '&Help')
self.SetMenuBar(menubar)
self.Centre()
self.Bind(wx.EVT_MENU, self.OnQuit, id=105)
def OnQuit(self, event):
self.Close()
class MyApp(wx.App):
def OnInit(self):
frame = MyMenu(None, -1, 'menu2.py')
frame.Show(True)
return True
app = MyApp(0)
app.MainLoop()
It’s mainly line 38 onwards that confuses me, as it defines another class MyApp. Should this not be a separate .PY module of type CLASS which then instantiates the MyMenu class? I’m using Eclipse, typed the entire code as is and tired to run it but got the error messages
Traceback (most recent call last):
File "C:\ws2\sample2\simple_gui\menu2.py", line 54, in <module>
app = MyApp(0)
File "C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 7981, in __init__
self._BootstrapApp()
File "C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 7555, in _BootstrapApp
return _core_.PyApp__BootstrapApp(*args, **kwargs)
File "C:\ws2\sample2\simple_gui\menu2.py", line 50, in OnInit
frame = MyMenu(None, -1, 'menu2.py')
File "C:\ws2\sample2\simple_gui\menu2.py", line 36, in __init__
menubar.Append(menu_file,'&Edit')
File "C:\Python27\lib\site-packages\wx-2.8-msw-unicode\wx\_core.py", line 11320, in Append
return _core_.MenuBar_Append(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "!m_menuBar" failed at ..\..\src\common\menucmn.cpp(820) in wxMenuBase::Attach(): attaching menu twice?
Can anyone shed some light as to why there would be 2 classes in the same py module? (note i’m a noob so assume entry level knowledge of OOP).
I got it working on my machine. But I’m really trying to understand what the code is doing, especially the app=MyApp(0) line. What does this do? what is the Zero for, why not another number like 3, or text like “hello”.
Having one (Frame or Panel) class per file is typical of wxPython coding.
Normally you build your frame without giving any special functionality and then you subclass it for that in another module. This way, especially when you work with gui buiding tools like wxGlade, you can modify the gui or even add new widgets to it independly of the code.
The second App class in your file is also typical of wxPython where it is very common to enclose the application details separated.
That said, in Python you can have as many clases per module as you want. Wether you have 1 or 5 depends on the functional completness of the module and how functionaly related are those classes.
In any case, when the module grows to more than 500-1000 lines it could be a good idea to split its contents in different files.
Finally, as commented above your code works perfect for me in win7 64-bits with wxpython 2.8. (I just had to comment the Set Bitmap line because I had not that image)
Edit: You are right. When you instantiate the Application object, the MyMenu frame is created and then the application enters its MainLoop. The App(value) is used to direct the application output to some places:
With App(1) if you set the parameter filename then you will sent the output to a file.
From
wx.App.__doc__:The signature of wx.App: