Posts: 34
Threads: 17
Joined: Dec 2019
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
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()
Posts: 12,026
Threads: 485
Joined: Sep 2016
use: result = widgetname.grid_location(x, y)
Posts: 34
Threads: 17
Joined: Dec 2019
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?
Posts: 12,026
Threads: 485
Joined: Sep 2016
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
Posts: 34
Threads: 17
Joined: Dec 2019
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()
Posts: 12,026
Threads: 485
Joined: Sep 2016
it needs to be applied to the widget, not an attribute of widget.
example: https://tkdocs.com/tutorial/grid.html
Posts: 34
Threads: 17
Joined: Dec 2019
Apr-24-2020, 10:53 PM
(This post was last modified: Apr-24-2020, 10:54 PM by kenwatts275.)
So what must be done to fix the program?
Which line of code is the problem?
Posts: 12,026
Threads: 485
Joined: Sep 2016
Apr-24-2020, 11:39 PM
(This post was last modified: Apr-24-2020, 11:39 PM by Larz60+.)
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': ''}
|