0

I am using tkinter and openpyxl to create a program that shows information in a textbox from an excel file when an option from a menu was chosen. In the excel file, first cell is the label listed on the option menu below it is the information that I want to appear in the textbox.

I used the same variable for the column number of the label and the information I need since they are in the same column. It shows the right label in the menu, but the information that appears in the textbox comes from a cell in the 11th column. I found out that it is taking the value from the while condition statement.

def info(column,row):
    textbox.insert(textbox.index("insert"), f"{{sheet1.cell(column=column, row=row).value}")
    

x = 1
while x < 11:
    for y in range(1, 10, 2):
        if not sheet1.cell(column=x, row=y).value == None:
            a_menu.add_command(label=f"{sheet1.cell(column=x, row=y).value}", command=lambda : info(x,2))
            pass
    x+=1

I tried creating a different variable and using another while and for loop, however, I am not sure how I will use them to work around the issue since I am really not sure where the problem is, my only guess is that I am not allowed to use a variable used in while condition statement as argument, is that correct? If not, what is the cause of the issue?

Note: I don't want blank cells to appear as None in the menu so I used an if not statement. The argument 2 is for testing only since I got stuck trying to fix the issue with the first argument.

1 Answers1

1

When using a lambda in a loop that also needs to pass a changing variable you need to safe a reference to the variable with the lambda.

If you do not save the reference what ends up happening is all lambda's created in this way will all run the last value assigned to x.

To do this you would change lambda: info(x,2) to lambda x=x: info(x,2).

Example in your code:

x = 1
while x < 11:
    for y in range(1, 10, 2):
        if not sheet1.cell(column=x, row=y).value == None:
            a_menu.add_command(label=f"{sheet1.cell(column=x, row=y).value}", command=lambda x=x: info(x,2))
            # pass  # this pass doesn't do anything. You can remove it.
    x+=1
Mike - SMT
  • 14,784
  • 4
  • 35
  • 79