import wx class MyFrame(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title, size=(400, 200)) self.CenterOnScreen() self.CreateStatusBar() self.SetStatusText("Status bar") class MyApp(wx.App): def OnInit(self): frame = MyFrame(None, -1, 'Hello World') frame.Show(True) self.SetTopWindow(frame) return True app = MyApp(0) app.MainLoop()
Before we Start
Today we will be adding a menu bar to the application that we created in the last tutorial. Menu bars are nice little horizontally based menus at the top of the window under the main frame section. They are used to holding quick functions and allowing you to locate things fast. Assuming you are looking at this tutorial in a browser right now you will see the menu bar at the top of the window that has File, Edit, View, Bookmarks (or Favorites depending on what browser you are using), and a few others.
Today, on our eventual goal of creating a syntax highlighter for multiple languages, we will be adding a file menu system. Something simple for the moment but it will become an integral portion of the application at a later time.
To start off open the previous file we made, and save a copy of it (just to make sure that nothing bad happens and you lose all your data.
The Code and What it does
We will start off by creating a general menu bar object (using the following code). Basically what it does, like most of wxPythons classes, is makes a pointer to the existing class and allows you to use it.:
menuBar = wx.MenuBar()
Now, that was simple, and we can go off and start population the menu with sections such as File, Edit, View, etc. To do this we must set up a new menu to be placed in the menu bar that we have created. This can be done with a simple call to wx.Menu() and will look like so for our program:
menu1 = wx.Menu()
Next step is to start populating the newly created menu. To get everything working out we will start off simple, and assuming that you messed around with the SetTitle() function, and managed to get it working before reading this tutorial you should have a little easier time understanding what we will be doing here in a minute.
Before that though we need to add some items to the menu, which can be accomplished like so:
menu1.Append(101, "Change &Title", "This will change the window title to ‘Some Title‘")
What the above code does is adds a menu item to menu1 (using the append function) and also gives it an id (101), Display text (&Change Title) and a Statusbar message (This will change the window title to ‘Some Title’). The id is required if you want to have any functions run off of the menu item.
Now we will take a brief pause from coding the menu so I can tell you a bit more about how it works.
The menu if a very nice little addition to programs, you have seen it in almost every application you can think of (from text editing to web browsing and beyond). Python, with the help of wxPython has made everything that much easier to use and shortcut. In the menu above you probably noticed the ampersand (&) in front of the display text (&Change Title) this is used for the Alt shortcuts on the menus. For instance if you were to press Alt+F you will likely get the file menu to pop open. Then if you were going open a file you could press O, making the whole shortcut look like so Alt+F+O.
Those shortcuts are all fine and dandy, but they tend to take a while to get going and are nowhere near as simple to use as a Ctrl+O shortcut to get the same result. WxPython has also allowed for people to easily add Ctrl+ shortcuts to their applications. After the display text you simply add \tCtrl+O to get the Ctrl+O shortcut, making the above code look like so:
menu1.Append(101, "Change &Title\tCtrl+T", "This will change the window title to ‘Some Title‘")
Now lets add a separator to the menu as well as a close option. To add a separator you can simply use:
Which will add a horizontal rule across the menu. Then to create a close option you would do the same type of thing we did for the Change Title option and add a new menu item:
menu1.Append(106, "&Close\tCtrl+W", "Closes the window")
NOTICE - I have left additional space between the ids of the Close Window item and the Change Title item, this is because we will not be keeping the Change Title item as we get further along with the application, but for now it is useful to teach you how to get the SetTitle function working if you haven’t experimented with it enough already to get it working. The Close Window item currently has the correct id and it will be staying at 106.
By now you are probably wondering how to see what you have created in the menu bar. This is accomplished by adding the menu we have created to the menu bar using this code:
Basically what it is doing is telling the menu bar to add the menu menu1 and call it File.
The next step is to get the menu bar set as the frame’s menu bar instead of just being some menu bar off in the middle of nowhere that doesn’t work with any of the frame(s). This portion of the code is no more difficult than the rest of it has been, you make one call and it works:
Now we get to move onto the fun stuff - making the menu items do something.
We will start off by declaring the close window function and telling it what to do (close the window). Just create a new function called CloseWindow and have the parameters or self and event passed to it and tell it to do this: self.Close(). If you haven’t yet mastered the art of creating functions in Python that is okay here is the code:
def CloseWindow(self, event): self.Close()
Next we need to create a function to change the title of the window, this can be done by creating a function called ChangeTitle and passing it the same two parameters then placing the following code inside of it:
Here is the full code if you are not comfortable with starting to place custom typed code into the file yet:
def ChangeTitle(self, event): self.SetTitle("Some Title")
Make sure that both of the previous functions are located within the MyFrame class, otherwise they won’t work.
Since we have the functions all set up and in place, ready to go, we need to make the rest of the program aware of them and tell it how to call them as well as when to do so. This can be done like so:
self.Bind(wx.EVT_MENU, self.ChangeTitle, id=101)
Above we are telling self (MyFrame) to Bind the menu event (wx.EVT_MENU) to with the function of ChangeTitle to the object with the id of 101 (also known as our Change Title menu item). It will act like so: Once the menu item (Change Title) is clicked the event is set off and the function ChangeTitle is called.
If you are starting to feel comfortable with this go ahead and try to get the CloseWindow function bound to its appropriate menu item.
Otherwise here is the code:
self.Bind(wx.EVT_MENU, self.CloseWindow, id=106)
Now you have finished adding a simple menu bar to your application! Here is a look at the whole code thus far:
import wx class MyFrame(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title, size=(400, 200)) self.CenterOnScreen() self.CreateStatusBar() self.SetStatusText("Status bar") menuBar = wx.MenuBar() menu1 = wx.Menu() menu1.Append(101, "Change &Title\tCtrl+T", "This will change the window title") menu1.AppendSeparator() menu1.Append(106, "&Close\tCtrl+W", "Closes the window") menuBar.Append(menu1, "&File") self.SetMenuBar(menuBar) self.Bind(wx.EVT_MENU, self.ChangeTitle, id=101) self.Bind(wx.EVT_MENU, self.CloseWindow, id=106) def CloseWindow(self, event): self.Close() def ChangeTitle(self, event): self.SetTitle("Some Title") class MyApp(wx.App): def OnInit(self): frame = MyFrame(None, -1, 'Hello World') frame.Show(True) self.SetTopWindow(frame) return True app = MyApp(0) app.MainLoop()
I have also attached a copy of the file so that all the tabs are in correct position and to allow you to see what it looks like with the correct positions.
Number of downloads: 570
If you are interested in exploring Python and wxPython outside of the tutorials here is something that will help you out on the next installment - Look into file handling (opening, saving and creating files). I understand that this could be a daunting task to start off with at this stage in your Python programming career but we will be going over the same thing in the next tutorial so if you get stuck don’t worry, we will be there to back you up.