Skip to content

Adding a GUI Feature

dmgaldi edited this page Jun 11, 2013 · 4 revisions

Get the source for oscaarGUI.py here.

In this tutorial we will look at the oscaarGUI.py script, which creates and shows the Graphical User Interface used when running oscaar. This is done by using the wxPython module. I will demonstrate how to create a drop down menu item that, when selected, calls a function in the oscaarGUI python script. When you open up oscaarGUI.py and scroll down you should see a block of code that looks like this:

self.menubar = wx.MenuBar() ##This is the main menubar where all menus are attached
self.fileMenu = wx.Menu()  ##File menu for quit
self.oscaarMenu = wx.Menu()  ##Menu for oscaar features
self.helpMenu = wx.Menu()

This is where the Menus that appear at the top of the GUI pane are initialized. The one we are concerned about is the self.oscaarMenu menu. This is the menu in which your feature is going to be added to. The first step in doing this is to create your menu item. In this example, we are going to create a menu item that opens up a new frame that displays a message. To do this, we append a menu item to the oscaar menu. This is done in python by adding the following line of code:

def InitUI(self):
...
    self.myMenuItem = self.oscaarMenu.Append(-1, 'My Item', 'Opens a test Frame!')

The first argument of the "Append" function is your menu item's ID. Because we do not really need it, we set it to -1. The second argument is they title of the menu item that will be displayed. The third argument sets the help field of the menu item. You can pretty much set this to whatever you want as it does not have a significant impact at all.

Our GUI feature is supposed to cause a new popup frame to appear. For this to happen, we need to create a class that defines the frame represents the frame that we want to appear. This can be done at the very end of the code:

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(MyFrame, self).__init__(*args, **kwargs)
        <Rest of Code>

app = wx.App(False)
#### Runs the GUI ####
OscaarFrame(None)
app.MainLoop()
#####END OF SCRIPT######

The class we are creating inherits the wx.Frame class. This means it acquires all of the functionality that the Frame class already has. This means we can set its size and add different control items such as buttons and text boxes to it. Now, we will add our own functionality to it. The init function of a class is called whenever an object of that class is created. When our frame is created we want it to initialize just as a wx.Frame would, and then we would like to do even more. This is why the first line in the init function is there.

Now we will set the size of the frame and add a button and message to it. This is done with the following code:

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwargs):
        super(MyFrame, self).__init__(*args, **kwargs)
        self.SetSize((250,100))  ##This sets the size of the frame (in pixels)
	self.SetBackgroundColour(wx.Colour(220,220,220)) ##This sets the frame's background color
        self.label = wx.StaticText(parent = self, id = -1, label = 'My Oscaar Feature', pos = (70,0)) 
        self.exitButton = wx.Button(parent = self, id = -1, label = 'Exit', pos = (75,30)) ##Adds a button
        self.Centre() ##Center the frame on screen
        self.Show(True)  ##Show the frame

This code first sets the size of the frame to 250 by 100 pixels. Next it sets the background color to something that looks a little more standard. Feel free to experiment with the color and make it look the way you want. The next line adds a StaticText object to the frame. This is a small area of text that cannot be edited. We set self as the parent and the we set the label and position. Finally we add the button and center and show the frame we have created. Now we want to make it so when the exit button is pressed, your frame terminates.

class MyFrame:
    def __init__:
        ...
    self.Show(True)
    self.exitButton.Bind(wx.EVT_BUTTON, self.quit)

    def quit(self, event):
        self.Destroy()

This code binds the exit button to the new function we created called quit(). This means when the button is pressed, the quit function will be called. In quit we put one line, self.Destroy. This destroys the instance of your frame that the button is a part of.

Now that we have finished creating our frame and our menu item, we have to link them somehow. When clicked, we want our menu item to create a new instance of the frame we defined. This is very similar to what we just did with the button we created. We will now define a function somewhere within the OscaarFrame class definition that will create an instance of our frame so that we can link it with our menu item.

class OscaarFrame(wx.Frame):
    ...
    def createMyFrame(self, event):
        MyFrame(self) ##set the parent of the frame to OscaarFrame

Now that that is done, the final step is to add one line of code to bind your new function to the menu item we created in the beginning of the tutorial. To do this, go back to where you created your menu item and add this line of code under it:

    self.myMenuItem = self.oscaarMenu.Append(-1, 'My Item', 'Opens a test Frame!')
    self.myMenuItem.Bind(wx.EVT_MENU, self.createMyFrame)

Now go ahead and run oscaar and your brand new menu item should be usable! Now you can change the code around and add whatever useful functionality to the oscaar GUI that you think needs.

Clone this wiki locally