Python Forum
Unable pass the proper row number to Menubutton command
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Unable pass the proper row number to Menubutton command
#1
Hi all,
I am trying to make a grid of multiselect entry boxes using Menubutton widgets.
Below is the example program I put together.
When the printValues function is called, the value 3 is always passed to it.
I need to pass the row number so that I can update the proper entry widget.

If I change the line
command=lambda:printValues(row_pos))
to
command=lambda:printValues(0))
it works for the first row. I need it to work for all rows.
Any help would be appreciated.
Thanks in advance.

from tkinter import *

def printValues(row_pos):
        selected_values = ""
        for name, var in menu_items[row_pos].items():
            if var.get() == 1:
                if selected_values == "":
                    selected_values = name
                else:
                    selected_values += ","+name
        print("Row: "+str(row_pos))
        entries[row_pos].delete(0,END)
        entries[row_pos].insert(0,selected_values)

if __name__ == "__main__":
    root = Tk()

    f1 = Frame(root)
    f1.pack()

    entries = []
    menus = []
    drop_down = ("Iron Man", "Superman", "Batman", "Hulk","Spiderman","Thor")
    menu_items = []

    max_rows = 3

    row_pos = 0
    while (row_pos < max_rows):
        entries.append(Entry(f1))
        entries[row_pos].grid(row=row_pos,column=0)

        menubutton = Menubutton(f1, indicatoron=True, borderwidth=1, relief="raised")
        menus.append(Menu(menubutton, tearoff=False))
        menubutton.configure(menu=menus[row_pos])
        menubutton.grid(row=row_pos,column=1)
        menu_items.append([])
        menu_items[row_pos] = {}

        for choice in drop_down:
            menu_items[row_pos][choice] = IntVar(value=0)
            menus[row_pos].add_checkbutton(label=choice, variable=menu_items[row_pos][choice],
                                 onvalue=1, offvalue=0,
                                 command=lambda:printValues(row_pos))

        row_pos += 1

    root.mainloop()
Reply
#2
You need to freeze the value of the passed argument, otherwise lambda tries to pull the variable from the current scope.
        for choice in drop_down:
            menu_items[row_pos][choice] = IntVar(value=0)
            menus[row_pos].add_checkbutton(label=choice, variable=menu_items[row_pos][choice],
                                 onvalue=1, offvalue=0,
                                 command=lambda x=row_pos:printValues(x))
You should also take a look at functools.partial. I find partial often works better than lambda for this sort of thing.
Reply
#3
Thanks deanhystad.
It worked. Easier than I thought.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] proper way of coding ebooczek 3 2,236 Feb-20-2022, 10:22 PM
Last Post: deanhystad

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020