Python Forum
Unable pass the proper row number to Menubutton command - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: GUI (https://python-forum.io/forum-10.html)
+--- Thread: Unable pass the proper row number to Menubutton command (/thread-28433.html)



Unable pass the proper row number to Menubutton command - kenwatts275 - Jul-19-2020

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()



RE: Unable pass the proper row number to Menubutton command - deanhystad - Jul-19-2020

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.


RE: Unable pass the proper row number to Menubutton command - kenwatts275 - Jul-19-2020

Thanks deanhystad.
It worked. Easier than I thought.