user2242044
user2242044

Reputation: 9253

Getting the row of a tkinter button in grid on click

I am writing a simple tkinter widget which a column of entry boxes and a column of buttons. The button should print the value in the corresponding entry box. I have essentially written all the code, but I have hardcoded the row label into my function:

print find_in_grid(root, 2, 0).get()

I need to instead replace the 2 with the row of the button that was clicked. How can I get that row?

Entire code:

from Tkinter import *

def print_value():
    print find_in_grid(root, 2, 0).get()


def find_in_grid(frame, row, column):
    for children in frame.children.values():
        info = children.grid_info()
        #note that rows and column numbers are stored as string
        if info['row'] == str(row) and info['column'] == str(column):
            return children
    return None

root = Tk()

height = 5
width = 1
for i in range(height): #Rows
    for j in range(width): #Columns
        b = Entry(root, text="", width=100)
        b.grid(row=i, column=j)

height = 5
width = 1
for i in range(height): #Rows
    for j in range(width): #Columns
        b = Button(root, text="print value", command=print_value, width=10)
        b.grid(row=i, column=j+1)


mainloop()

Upvotes: 1

Views: 8025

Answers (2)

Austin Grayson
Austin Grayson

Reputation: 5

This does not work as “Button” is not defined, it has to be:

buttonName = tk.button(windowName, text=“TEXT”, command=functionName

Although, when this is in, there are multiple slaves in the variable.

Upvotes: 0

Kevin
Kevin

Reputation: 76254

You could pass the row and column values as arguments to print_value. Don't forget to use the default variable trick when binding the command, or else it will always think you clicked the bottom-right button.

def print_value(row, col):
    print find_in_grid(root, row, col).get()

#...

height = 5
width = 1
for i in range(height): #Rows
    for j in range(width): #Columns
        b = Button(root, text="print value", command=lambda i=i,j=j: print_value(i,j), width=10)
        b.grid(row=i, column=j+1)

You could also pass in the entry objects directly, but this requires some refactoring:

from Tkinter import *

def print_value(entry):
    print entry.get()

root = Tk()

height = 5
width = 1
for i in range(height): #Rows
    for j in range(width): #Columns
        entry = Entry(root, text="", width=100)
        entry.grid(row=i, column=j)
        b = Button(root, text="print value", command= lambda entry=entry: print_value(entry), width=10)
        b.grid(row=i, column=j+1)

mainloop()

Upvotes: 3

Related Questions