Tkinter.Menu() Question

Discussion in 'Python' started by Adonis, Jan 4, 2004.

  1. Adonis

    Adonis Guest

    I wish to create a popup menu from a list, when it is created they all show
    the same label from the list:

    Months = [0, 'January', 'February', 'March', 'April', 'May', 'June',
    'July', 'August', 'September', 'October', 'November',
    'December']

    def _Menu_Click(self, month):
    print month

    menu = Menu(fraMain, tearoff=0)

    for Month in Months[1:]:
    menu.add_command(label=Month, command=lambda : _Menu_Click(Month))

    When the menu calls _Menu_Click(...) it always prints 'December'

    Now my understanding is the when an object is created and it is replicated,
    whichever of the modified replications affects all of the objects, being
    that they are just mere references to the original (my wording might be off,
    correct me if I am wrong). How do I avoid this for what I am trying to
    achieve?

    Any help is greatly appreciated.

    Adonis
    Adonis, Jan 4, 2004
    #1
    1. Advertising

  2. Adonis

    Peter Otten Guest

    Adonis wrote:

    > I wish to create a popup menu from a list, when it is created they all
    > show the same label from the list:
    >
    > Months = [0, 'January', 'February', 'March', 'April', 'May', 'June',
    > 'July', 'August', 'September', 'October', 'November',
    > 'December']
    >
    > def _Menu_Click(self, month):
    > print month
    >
    > menu = Menu(fraMain, tearoff=0)
    >
    > for Month in Months[1:]:
    > menu.add_command(label=Month, command=lambda : _Menu_Click(Month))
    >
    > When the menu calls _Menu_Click(...) it always prints 'December'
    >
    > Now my understanding is the when an object is created and it is
    > replicated, whichever of the modified replications affects all of the
    > objects, being that they are just mere references to the original (my
    > wording might be off, correct me if I am wrong). How do I avoid this for
    > what I am trying to achieve?


    (I made some bogus changes so I could ensure it works)

    from Tkinter import *

    Months = [0, 'January', 'February', 'March', 'April', 'May', 'June',
    'July', 'August', 'September', 'October', 'November',
    'December']

    root = Tk()

    class DontCare:
    def _Menu_Click(self, month):
    print month
    dc = DontCare()

    mb = Menubutton(root, text="so what")
    mb.pack()
    menu = mb["menu"] = Menu(mb, tearoff=0)


    for Month in Months[1:]:
    menu.add_command(label=Month, command=lambda m=Month: dc._Menu_Click(m))

    root.mainloop()

    Note how the instance (dc) is provided with the method (_Menu_Click) in the
    lambda (in your real code you will most likely have to replace dc with
    self). The real trick is to provide the loop variable Month as the default
    value for m in the lambda. m will be bound to the same string as Month when
    the lambda is *created*. If you don't do this, the value of the variable
    Month will be looked up when the lambda is *called*, which will be always
    "December" after the for loop is terminated.

    Peter
    Peter Otten, Jan 4, 2004
    #2
    1. Advertising

  3. Adonis

    Adonis Guest

    "Peter Otten" <> wrote in message
    news:bt9v6d$s3n$07$-online.com...
    > Adonis wrote:
    >
    > > I wish to create a popup menu from a list, when it is created they all
    > > show the same label from the list:
    > >
    > > Months = [0, 'January', 'February', 'March', 'April', 'May', 'June',
    > > 'July', 'August', 'September', 'October', 'November',
    > > 'December']
    > >
    > > def _Menu_Click(self, month):
    > > print month
    > >
    > > menu = Menu(fraMain, tearoff=0)
    > >
    > > for Month in Months[1:]:
    > > menu.add_command(label=Month, command=lambda : _Menu_Click(Month))
    > >
    > > When the menu calls _Menu_Click(...) it always prints 'December'
    > >
    > > Now my understanding is the when an object is created and it is
    > > replicated, whichever of the modified replications affects all of the
    > > objects, being that they are just mere references to the original (my
    > > wording might be off, correct me if I am wrong). How do I avoid this for
    > > what I am trying to achieve?

    >
    > (I made some bogus changes so I could ensure it works)
    >
    > from Tkinter import *
    >
    > Months = [0, 'January', 'February', 'March', 'April', 'May', 'June',
    > 'July', 'August', 'September', 'October', 'November',
    > 'December']
    >
    > root = Tk()
    >
    > class DontCare:
    > def _Menu_Click(self, month):
    > print month
    > dc = DontCare()
    >
    > mb = Menubutton(root, text="so what")
    > mb.pack()
    > menu = mb["menu"] = Menu(mb, tearoff=0)
    >
    >
    > for Month in Months[1:]:
    > menu.add_command(label=Month, command=lambda m=Month:

    dc._Menu_Click(m))
    >
    > root.mainloop()
    >
    > Note how the instance (dc) is provided with the method (_Menu_Click) in

    the
    > lambda (in your real code you will most likely have to replace dc with
    > self). The real trick is to provide the loop variable Month as the default
    > value for m in the lambda. m will be bound to the same string as Month

    when
    > the lambda is *created*. If you don't do this, the value of the variable
    > Month will be looked up when the lambda is *called*, which will be always
    > "December" after the for loop is terminated.
    >
    > Peter


    Thanks a million, works like a charm.

    Adonis
    Adonis, Jan 4, 2004
    #3
  4. Adonis

    John Grayson Guest

    Try:

    for Month in Months[1:]:
    menu.add_command(label=Month, command=lambda m=Month : \
    _Menu_Click(m))



    Adonis wrote:

    > I wish to create a popup menu from a list, when it is created they all show
    > the same label from the list:
    >
    > Months = [0, 'January', 'February', 'March', 'April', 'May', 'June',
    > 'July', 'August', 'September', 'October', 'November',
    > 'December']
    >
    > def _Menu_Click(self, month):
    > print month
    >
    > menu = Menu(fraMain, tearoff=0)
    >
    > for Month in Months[1:]:
    > menu.add_command(label=Month, command=lambda : _Menu_Click(Month))
    >
    > When the menu calls _Menu_Click(...) it always prints 'December'
    >
    > Now my understanding is the when an object is created and it is replicated,
    > whichever of the modified replications affects all of the objects, being
    > that they are just mere references to the original (my wording might be off,
    > correct me if I am wrong). How do I avoid this for what I am trying to
    > achieve?
    >
    > Any help is greatly appreciated.
    >
    > Adonis
    >
    >
    John Grayson, Jan 7, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kevin Walzer
    Replies:
    5
    Views:
    566
    Kevin Walzer
    Mar 30, 2007
  2. Axel
    Replies:
    1
    Views:
    635
  3. galyle
    Replies:
    6
    Views:
    304
    galyle
    Oct 4, 2011
  4. Karl-Inge Reknes

    Menu question (list menu)

    Karl-Inge Reknes, Dec 22, 2006, in forum: ASP .Net Web Controls
    Replies:
    0
    Views:
    148
    Karl-Inge Reknes
    Dec 22, 2006
  5. Bonge Boo!
    Replies:
    5
    Views:
    186
    Bonge Boo!
    Apr 25, 2005
Loading...

Share This Page