Why is it so freaking hard to find simple examples of so much stuff in the Python version of tkinter!?
The web is full of folks who want to use a loop to produce a bunch of widgets, but then can’t figure out how to address them since they were not assigned variable names. There are several approaches to solve this conundrum. tkinter has a set of perfectly good tools to use – but just try and find simple, non-geeky @$%#%^ examples of how they work. So this rant and the little demo code below demonstrates:
grid_location(x,y)
grid_slaves(row, column)
using str() to grab a pathname – thanks Mr. Shipman at New Mexico Tech
nametowidget(widget pathname)
winfo_atom
winfo_atomname
Some combination of the above can almost certainly get you the information you need, and they are all simple to use:
# TEST AREA for Widget Identity
# (c) 2018 John A. Oakey
# permission given to use for non-commercial purposes
# standard set up header code 2
from tkinter import *
root = Tk()
root.attributes('-fullscreen', True)
root.configure(background='SteelBlue4')
scrW = root.winfo_screenwidth()
scrH = root.winfo_screenheight()
workwindow = str(1024) + "x" + str(768)+ "+" +str(int((scrW-1024)/2)) + "+" +str(int((scrH-768)/2))
top1 = Toplevel(root, bg="light blue")
top1.geometry(workwindow)
top1.title("Top 1 - Workwindow")
top1.attributes("-topmost", 1) # make sure top1 is on top to start
root.update() # but don't leave it locked in place
top1.attributes("-topmost", 0) # in case you use lower or lift
#exit button - note: uses grid
b3=Button(root, text="Egress", name="eb3", command=root.destroy)
b3.grid(row=0,column=0,ipadx=10, ipady=10, pady=5, padx=5, sticky = W+N)
#____________________________
# first let's make a bunch of unnamed label widgets and a text box for our observations
for i in range(1,5):
for x in range(1,5):
nextlabel = Label(top1, width=25, height=2, bg="linen")
nextlabel.grid(column = i, row = x, padx=10, pady=10, ipadx=5, ipady=5)
nextlabel.configure(text = top1.winfo_atomname(top1.winfo_atom(nextlabel, displayof=0), displayof=0))
tx1=Text(top1, width=90, height=20)
tx1.grid(column=1,row=6,columnspan=5, pady=20, padx=20)
def tline(line):
tx1.insert(END, line)
tx1.insert(END, "\n")
x,y=700,300 # some random pixel points in the grid to find
gtup = top1.grid_location(x,y) # given pixel location, grid_location returns grid column and row
tline("These are the row and column integers: " + str(gtup) + " *0 was not used")
top1_slave = top1.grid_slaves(gtup[0], gtup[1]) # given col and row, grid_slaves return tuple of widgit slaves
w_pathname=str(top1_slave[0]) # only one widget which will be [0] - holds pathname .!toplevel.!label15
tline("This is variable w_pathname which is our label pathname extracted: "+ w_pathname)
w_id=(root.nametowidget(w_pathname)) # convert pathname to widget name with nametowidget function
tline("Using nametowidget we convert it to a widget name: "+ str(w_id)) # will look the same in print but it is not - can't substitute
tline("It looks the same printed but internally it is not.")
tline("Changing our target widget bg color to prove we have the goods.")
w_id.configure(bg="coral1") # proof we can use it to affect a widget option attributes
# with name in variable w_id and pathname in variable w_pathname we can get id with winfo_atom
tline("The widget id integer is extracted to w_id with winfo_atom: " + str(w_id.winfo_atom(w_pathname,displayof=0)))
id_int = w_id.winfo_atom(w_pathname,displayof=0)
# and knowing the pathname and id integer we can come full circle and use it to find the widget name
w_name2=w_id.winfo_atomname(id_int, displayof=0)
tline("Using the name and atom we come full circle to geth the atomname: "+ str(w_name2))
tline("Are w_name2 and w_pathname the same?")
if w_name2==w_pathname:
tline("w_name2 and w_pathname are the same")
else:
tline("not so much")
tline("Are w_name2 and w_id the same?")
if w_name2==w_id:
tline("w_name2 and w_id are the same")
else:
tline("not so much")
#____________________________
root.mainloop()

