Python Forum

Full Version: How to retreive the grid location of an Entry widget
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello everyone,
I am trying to get the grid position of an Entry widget on focus out.
The code below always seems to return row 4 column 1 no matter which Entry widget I am on.
Any help would be appreciated.
Thanks in advance Smile


from tkinter import *
from tkinter import ttk

def set_input(frame,i,j):
    print("row "+str(i)+", column "+str(j))
    return(True)

mw = Tk()
mw.geometry('600x200+400+200')
mw.title("test program")

frame1 = Frame(mw)
frame1.pack(side=TOP)
framebot = Frame(mw)
framebot.pack(side=BOTTOM,fill=X)

field_labels = ["field1","field2","field3"]
values = []
for i in range(0,5):
       values.append([])
       j = 0
       values[i].append(Entry(frame1,validate="focusout",validatecommand=lambda:set_input(frame1,i,j)))
       values[i][j].grid(row=i,  column= j)
       j += 1
       values[i].append(ttk.Combobox(frame1,values=field_labels,validate="focusout",validatecommand=lambda:set_input(frame1,i,j)))
       values[i][j].grid(row=i,  column= j)

btn = Button(framebot,text='Exit',font=("Times",16),command=mw.quit).pack(side="left")

mw.mainloop()
use: result = widgetname.grid_location(x, y)
Thank you for your quick response Larz60.
So exactly how do I use this widgetname.grid_location(x,y) method in my program?
How do I get the values for x and y?
I gave you the wrong command (Shipman 4.2 w.grid_location(x, y))
Quote:w.grid_location(x, y)
Given a coordinates (x, y) relative to the containing widget, this method returns a tuple (col,
row) describing what cell of w's grid system contains that screen coordinate.
I think you want:
Quote:w.grid_info()
Returns a dictionary whose keys are w's option names, with the corresponding values of those options.
you can get a copy of John Shipman's reference here: reu.cct.lsu.edu/documents/Python_Course/tkinter.pdf
Thank you Larz60,
I tried using the grid_info method and it is still returning row 4 column 1 no matter which entry widget I am entering values.


from tkinter import *
from tkinter import ttk

def set_input(frame,self):
    row = self.grid_info()["row"]
    col = self.grid_info()["column"]
    print("row "+str(row)+", column "+str(col))
    return(True)

mw = Tk()
# 999x999 is size of window, 999+999 is the location of the window
mw.geometry('600x200+400+200')
mw.title("test program")

frame1 = Frame(mw)
frame1.pack(side=TOP)
framebot = Frame(mw)
framebot.pack(side=BOTTOM,fill=X)

field_labels = ["field1","field2","field3"]
values = []
for i in range(0,5):
       values.append([])
       j = 0
       values[i].append(Entry(frame1,validate="focusout",validatecommand=lambda:set_input(frame1,values[i][j])))
       values[i][j].grid(row=i,  column= j)
       j += 1
       values[i].append(ttk.Combobox(frame1,values=field_labels,validate="focusout",validatecommand=lambda:set_input(frame1,values[i][j])))
       values[i][j].grid(row=i,  column= j)

btn = Button(framebot,text='Exit',font=("Times",16),command=mw.quit).pack(side="left")

mw.mainloop()
it needs to be applied to the widget, not an attribute of widget.
example: https://tkdocs.com/tutorial/grid.html
So what must be done to fix the program?
Which line of code is the problem?
I'm going to let you decipher where the entry widget is embedded, but this code holds the answer.
The way you have complicated the widget array makes me dizzy and you are more familiar with your code
from tkinter import *
from tkinter import ttk


def set_input(frame, self):
    row = self.grid_info()["row"]
    col = self.grid_info()["column"]
    # print("row " + str(row) + ", column " + str(col))
    return True

mw = Tk()
# 999x999 is size of window, 999+999 is the location of the window
mw.geometry("600x200+400+200")
mw.title("test program")

frame1 = Frame(mw)
frame1.pack(side=TOP)
framebot = Frame(mw)
framebot.pack(side=BOTTOM, fill=X)

field_labels = ["field1", "field2", "field3"]
values = []
for i in range(0, 5):
    values.append([])
    j = 0
    values[i].append(
        Entry(
            frame1,
            validate="focusout",
            validatecommand=lambda: set_input(frame1, values[i][j]),
        )
    )
    values[i][j].grid(row=i, column=j)
    j += 1
    values[i].append(
        ttk.Combobox(
            frame1,
            values=field_labels,
            validate="focusout",
            validatecommand=lambda: set_input(frame1, values[i][j]),
        )
    )
    values[i][j].grid(row=i, column=j)
    print(f"row: {values[i][0].grid_info()}")
    print(f"row: {values[i][1].grid_info()}")

btn = Button(framebot, text="Exit", font=("Times", 16), command=mw.quit).pack(
    side="left"
)

mw.mainloop()
The answer is here, you just have to pull out with the right indexes.
Your lists seem way over compilcated

results when run:
Output:
row: {'in': <tkinter.Frame object .!frame>, 'column': 0, 'row': 0, 'columnspan': 1, 'rowspan': 1, 'ipadx': 0, 'ipady': 0, 'padx': 0, 'pady': 0, 'sticky': ''} row: {'in': <tkinter.Frame object .!frame>, 'column': 1, 'row': 0, 'columnspan': 1, 'rowspan': 1, 'ipadx': 0, 'ipady': 0, 'padx': 0, 'pady': 0, 'sticky': ''} row: {'in': <tkinter.Frame object .!frame>, 'column': 0, 'row': 1, 'columnspan': 1, 'rowspan': 1, 'ipadx': 0, 'ipady': 0, 'padx': 0, 'pady': 0, 'sticky': ''} row: {'in': <tkinter.Frame object .!frame>, 'column': 1, 'row': 1, 'columnspan': 1, 'rowspan': 1, 'ipadx': 0, 'ipady': 0, 'padx': 0, 'pady': 0, 'sticky': ''} row: {'in': <tkinter.Frame object .!frame>, 'column': 0, 'row': 2, 'columnspan': 1, 'rowspan': 1, 'ipadx': 0, 'ipady': 0, 'padx': 0, 'pady': 0, 'sticky': ''} row: {'in': <tkinter.Frame object .!frame>, 'column': 1, 'row': 2, 'columnspan': 1, 'rowspan': 1, 'ipadx': 0, 'ipady': 0, 'padx': 0, 'pady': 0, 'sticky': ''} row: {'in': <tkinter.Frame object .!frame>, 'column': 0, 'row': 3, 'columnspan': 1, 'rowspan': 1, 'ipadx': 0, 'ipady': 0, 'padx': 0, 'pady': 0, 'sticky': ''} row: {'in': <tkinter.Frame object .!frame>, 'column': 1, 'row': 3, 'columnspan': 1, 'rowspan': 1, 'ipadx': 0, 'ipady': 0, 'padx': 0, 'pady': 0, 'sticky': ''} row: {'in': <tkinter.Frame object .!frame>, 'column': 0, 'row': 4, 'columnspan': 1, 'rowspan': 1, 'ipadx': 0, 'ipady': 0, 'padx': 0, 'pady': 0, 'sticky': ''} row: {'in': <tkinter.Frame object .!frame>, 'column': 1, 'row': 4, 'columnspan': 1, 'rowspan': 1, 'ipadx': 0, 'ipady': 0, 'padx': 0, 'pady': 0, 'sticky': ''}