Zientzilaria

Covering the bioinformatics niche and much more

Creating an Interface for the Motif Finding Script, Part 4

| Comments

Last time we checked how to add a menu to our simple frame. Unfortunately, just adding it won’t make the menu useful. In order to do that we need to bind some events to it. As any interface framework, wxPython is governed by events generated by the user, being these events mouse clicks on buttons and menus, objects getting/losing focus, etc. In our case, so far, we evidently need a event called menu event, which will tell the code what path to use when a menu is clicked. My personal preference for binding an event to menu is to create a separate function to store these procedures, __do_binding. But by using this route we would need to change some code in the menu declaration, and to simplify things we will add the menu binding at the end of the __do_layout function. And how we create a binding? In order to bind an object/menu to a function that will contain the executed code after the event is fired up, we need the name of the object/menu, the target function and the menu type. We already know the first and the last, we just need the function name then. Remember that we created the menu last time by using (the menu name were changed in the previous entry – it was some old code that got in the way – my mistake)

1
2
3
4
foreground_menu = filemenu.Append(-1, 'Select foreground file')
background_menu = filemenu.Append(-1, 'Select background file')
...
quitmenu = filemenu.Append(-1, 'Quit')

hence our menu names are foreground_menu, background_menu and quit_menu. Basically a wx.Bind method has this structure

1
self.Bind(EVENT_TYPE, handler, source)

where the handler is the function and the source is the actual source of the event. Let’s say then we want to use function on_foreground every time someone clicks on foreground menu, and on_background every time someone clicks on the background menu. We add a couple of lines to our layout function

1
2
3
s
self.Bind(wx.EVT_MENU, self.on_foreground, foreground_menu)
self.Bind(wx.EVT_MENU, self.on_background, background_menu)

This will tell the code where to go when these items are clicked. If you start the interface, and error will be generated because we still haven’t created the event handler functions. We should define them

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/env python

import wx
import pymot
import fasta

class pymot(wx.App):

    def __init__(self, redirect=False):
        wx.App.__init__(self, redirect)

class pymotGUI(wx.Frame):

    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id,  'Python Motif Finder', style=wx.DEFAULT_FRAME_STYLE)
        self.__do_layout()

    def __do_layout(self):

        #adding the panel
        panel = wx.Panel(self)

        #defines the menubar
        menubar = wx.MenuBar()

        #file menu
        filemenu = wx.Menu()
        foreground_menu = filemenu.Append(-1, 'Select foreground file')
        background_menu = filemenu.Append(-1, 'Select background file')
        sep = filemenu.AppendSeparator()
        quitmenu = filemenu.Append(-1, 'Quit')

        #appends the menu to the menubar and creates it
        menubar.Append(filemenu, 'File')
        self.SetMenuBar(menubar)

        self.Bind(wx.EVT_MENU, self.on_foreground, foreground_menu)
        self.Bind(wx.EVT_MENU, self.on_background, background_menu)

    def on_foreground(self, event):
        pass

    def on_background(self, event):
        pass

app = pymot()
frame = pymotGUI(parent=None, id = -1)
frame.Show()
app.MainLoop()

Next time we will make good use of the events.