wxPython menu from lists

I have a set of menus which I am developing in a project. Here is the basic code:

#Define main menu bar with sub-menus

OverMenuBar = wx.MenuBar()

#Define FileMenu

FileMenu = wx.Menu()

NewItem = FileMenu.Append(-1, “New”, “New item”)

OpenItem = FileMenu.Append(-1, “Open”, “Open file”)

self.Bind(wx.EVT_MENU, self.OnNew, NewItem)

self.Bind(wx.EVT_MENU, self.OnOpen, OpenItem)

OverMenuBar.Append(FileMenu, “File”)

self.SetMenuBar(OverMenuBar)

def OnNew(self, event):

wx.MessageBox(“New item”)

def OnOpen(self, event):

wx.MessageBox(“Open item”)

I would like to do this all with lists, because it would eliminate a bunch of duplicate code.

I am beginning with:

omitems = [(((“New”, “New item”, OnNew),

(“Open”, “Open file”, OnOpen)),“File”)]

for oitem in omitems:

oMenu = wx.Menu()

Link = []

iMenu = oMenu[0]

#print FileMenu

for item in iMenu:

Link = oMenu.Append(-1, item[0], item[1])

print item

FileLink.append(Link)

self.Bind(wx.EVT_MENU, self.item[2], Link)

OverMenuBar.Append(oMenu, oitem[1])

I get an error:

NameError: global name ‘OnNew’ is not defined

when the list omitems is being read.

I am a little confused with how to put functions into list. How do I define OnNew as a function so that I can use this abstract approach?

You gave the subroutine name in your list a different name than the actual subroutine,
and the Bind statement was incorrect as well, though you didn't get that far.

         omitems = [((("New", "New item", self.OnNew),
                           ("Open", "Open file", self.OnOpen)),"File")]

and the Bind should be:

                 self.Bind(wx.EVT_MENU, item[2], Link)

···

On 8/29/2014 9:28 AM, Paul Thompson wrote:

I have a set of menus which I am developing in a project. Here is the basic code:

#Define main menu bar with sub-menus
        OverMenuBar = wx.MenuBar()
#Define FileMenu
        FileMenu = wx.Menu()
        NewItem = FileMenu.Append(-1, "New", "New item")
        OpenItem = FileMenu.Append(-1, "Open", "Open file")

        self.Bind(wx.EVT_MENU, self.OnNew, NewItem)
        self.Bind(wx.EVT_MENU, self.OnOpen, OpenItem)

        OverMenuBar.Append(FileMenu, "File")
        self.SetMenuBar(OverMenuBar)

    def OnNew(self, event):
        wx.MessageBox("New item")
    def OnOpen(self, event):
        wx.MessageBox("Open item")

I would like to do this all with lists, because it would eliminate a bunch of duplicate code.

I am beginning with:
        omitems = [((("New", "New item", OnNew),
                          ("Open", "Open file", OnOpen)),"File")]
        for oitem in omitems:
            oMenu = wx.Menu()
            Link =
            iMenu = oMenu[0]
            #print FileMenu
            for item in iMenu:
                Link = oMenu.Append(-1, item[0], item[1])
                print item
                FileLink.append(Link)
                self.Bind(wx.EVT_MENU, self.item[2], Link)
            OverMenuBar.Append(oMenu, oitem[1])

I get an error:
NameError: global name 'OnNew' is not defined
when the list omitems is being read.

I am a little confused with how to put functions into list. How do I define OnNew as a function so that I can use this abstract approach?

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com <mailto:wxpython-users+unsubscribe@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.

Thanks, Rufus. Indeed, this did work. What should I read to understand this issue better? I suppose it’s clear that my understanding of the class constructor is a little less than perfect.

···

On Friday, August 29, 2014 1:42:24 PM UTC-5, Rufus wrote:

  You gave the subroutine name in your

list a different name than the actual subroutine,

  and the Bind statement was incorrect as well, though you didn't

get that far.

omitems = [(((“New”, “New item”, self.OnNew),

    ("Open", "Open file",

self.OnOpen)),“File”)]

  and the Bind should be:

self.Bind(wx.EVT_MENU, item[2], Link)

  On 8/29/2014 9:28 AM, Paul Thompson wrote:
    I have a set of menus which I am developing in a

project. Here is the basic code:

#Define main menu bar with sub-menus

OverMenuBar = wx.MenuBar()

#Define FileMenu

FileMenu = wx.Menu()

NewItem = FileMenu.Append(-1, “New”, “New item”)

        OpenItem = FileMenu.Append(-1, "Open", "Open

file")

self.Bind(wx.EVT_MENU, self.OnNew, NewItem)

self.Bind(wx.EVT_MENU, self.OnOpen, OpenItem)

OverMenuBar.Append(FileMenu, “File”)

self.SetMenuBar(OverMenuBar)

def OnNew(self, event):

wx.MessageBox(“New item”)

def OnOpen(self, event):

wx.MessageBox(“Open item”)

      I would like to do this all with lists, because it would

eliminate a bunch of duplicate code.

I am beginning with:

omitems = [(((“New”, “New item”, OnNew),

        ("Open", "Open file",

OnOpen)),“File”)]

for oitem in omitems:

oMenu = wx.Menu()

Link =

iMenu = oMenu[0]

#print FileMenu

for item in iMenu:

          Link = oMenu.Append(-1, item[0],

item[1])

print item

FileLink.append(Link)

          self.Bind(wx.EVT_MENU, self.item[2],

Link)

OverMenuBar.Append(oMenu, oitem[1])

I get an error:

NameError: global name ‘OnNew’ is not defined

when the list omitems is being read.

      I am a little confused with how to put functions into list.

How do I define OnNew as a function so that I can use this
abstract approach?

  You received this message because you are subscribed to the Google

Groups “wxPython-users” group.

  To unsubscribe from this group and stop receiving emails from it,

send an email to wxpython-user...@googlegroups.com.

  For more options, visit [https://groups.google.com/d/optout](https://groups.google.com/d/optout).

self is just what you have passed into the init as the first arg (and also the first arg of all class methods), so that defines the ‘self’ variable as being the the current object you’re working on. You could call it anything, but the first arg in class methods works like that, the current object is passed.

Any functions in a class are methods (just what you call a function that is in a class), and unless you have @classmethod above the method definition (def myMethod(self, arg1):slight_smile: it is an object method… so you access it from inside other class methods by calling self.methodName(arg1). If you want to call methodName on that object, but doing so outside the class methods, then you just do myObject.methodName(arg1).

It can take a while to understand the reference mechanisms in python, and objects. In fact, I misspoke when I said you
had a different name than the actual subroutine, when I should have said a different reference. Python is all about the
references.

Your original list had OnNew as one of the items, The interpreter looked for OnNew in the local dictionary of
the function you were running (__init__). When it didn't find it, it looked in the global dictionary, and
not finding it there, gave you the error message.

by specifying self.OnNew instead, the interpreter looks up self reference (which was the first argument in
the argument list of __init__,( defined something like: def __init__(self,...): )

which makes self refer to the new object you are creating. Then the . operator tells it to find an attribute
of that object. The attribute name being OnNew, defined somewhere in your class definition as:

def OnNew(self,...):

Which is an executable object. So now your list has a reference to that OnNew method you defined.

The self in self.Bind() uses the self reference to look for the Bind referenence , and when it is not in your
immediate class definition, it looks to the parent class (like wx.Frame) for the Bind method. One of the
parameters that Bind expects is an executable object, so you gave the same reference as self.OnNew that
you had stored in your list, the list and the item references were created within the subroutine, so they
do not get the self. prefix, as they are just local variables.

Google for python objects, or objects in python, as am sure you can find more thorough treatement.

···

On 8/29/2014 4:20 PM, Paul Thompson wrote:

Thanks, Rufus. Indeed, this did work. What should I read to understand this issue better? I suppose it's clear that my understanding of the class constructor is a little less than perfect.

On Friday, August 29, 2014 1:42:24 PM UTC-5, Rufus wrote:

    You gave the subroutine name in your list a different name than
    the actual subroutine,
    and the Bind statement was incorrect as well, though you didn't
    get that far.

            omitems = [((("New", "New item", self.OnNew),
                              ("Open", "Open file", self.OnOpen)),"File")]

    and the Bind should be:

                    self.Bind(wx.EVT_MENU, item[2], Link)

    On 8/29/2014 9:28 AM, Paul Thompson wrote:

    I have a set of menus which I am developing in a project. Here is
    the basic code:

    #Define main menu bar with sub-menus
            OverMenuBar = wx.MenuBar()
    #Define FileMenu
            FileMenu = wx.Menu()
            NewItem = FileMenu.Append(-1, "New", "New item")
            OpenItem = FileMenu.Append(-1, "Open", "Open file")

            self.Bind(wx.EVT_MENU, self.OnNew, NewItem)
            self.Bind(wx.EVT_MENU, self.OnOpen, OpenItem)

            OverMenuBar.Append(FileMenu, "File")
            self.SetMenuBar(OverMenuBar)

        def OnNew(self, event):
            wx.MessageBox("New item")
        def OnOpen(self, event):
            wx.MessageBox("Open item")

    I would like to do this all with lists, because it would
    eliminate a bunch of duplicate code.

    I am beginning with:
            omitems = [((("New", "New item", OnNew),
                              ("Open", "Open file", OnOpen)),"File")]
            for oitem in omitems:
                oMenu = wx.Menu()
                Link =
                iMenu = oMenu[0]
                #print FileMenu
                for item in iMenu:
                    Link = oMenu.Append(-1, item[0], item[1])
                    print item
                    FileLink.append(Link)
                    self.Bind(wx.EVT_MENU, self.item[2], Link)
                OverMenuBar.Append(oMenu, oitem[1])

    I get an error:
    NameError: global name 'OnNew' is not defined
    when the list omitems is being read.

    I am a little confused with how to put functions into list. How
    do I define OnNew as a function so that I can use this abstract
    approach?

    -- You received this message because you are subscribed to the
    Google Groups "wxPython-users" group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to wxpython-user...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/d/optout
    <https://groups.google.com/d/optout&gt;\.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com <mailto:wxpython-users+unsubscribe@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.