11

Note that by widget this excludes canvas items (which aren't widgets).

My goal is to build two classes: one that produces items of a canvas widget, the other producing widgets themselves. This is to ensure I can move stuff around in the window and keep it there upon reopening. I've already done this for canvas items. You see, canvas widgets actually return an actual ID that remains constant for the respected items, thus I can reference that and it's coords.

However, for widgets themselves, there seems to be no such way of obtaining an ID. I've tried widget.getint(), widget.getvar() , etc. I've also tried repr(widget) and id(widget), but both of these values change upon reopening, am thinking that new widgets are created, where the variable just refers to a newly created widget in comparison to the one just destroyed, even if it has identical properties.

I've also tried putting said widgets in a parent window, like window, or frame, but these widgets themselves do not assign any unique values to their respective child widgets.

So basically, I can obtain unique values of any given widget, but none that are constant. This could by any value by the way, for I shall just turn it to a string, append it to a dict, and assign the coords to said str to reference a specific widget.

Thank you in advance for any guidance, it is much appreciated :)

Jim Jam
  • 713
  • 4
  • 10
  • 22
  • [`repr(widget)`](http://stackoverflow.com/questions/7784148/understanding-repr-function-in-python) returns a string representation of the widget. [`id(widget)`](https://docs.python.org/3.4/library/functions.html#id) returns basically a number representing the address of the object in memory. Note that `id(widget)` returns always the same number during the same application instance. It could return different numbers for the "same" object in different instances of your application. – nbro May 02 '15 at 22:29
  • By application instance I mean when you run your application, that's an instance, when you run it another time, that's another instance, and so on. – nbro May 02 '15 at 22:31

2 Answers2

14

You can't get a unique, constant ID, but you can give widgets a unique, constant ID.

Under the hood, tkinter uses tk. In tk, every widget has a name, and lives in a hierarchy expressed via dot notation. In tk you must define a name when creating a widget; this is something that tkinter does for you. When you see a widget name like ".1234567890.0987654f321", that means that the parent has the internal name of ".1234567890" and the widget is named "0987654321".

You can override the auto-generated name by giving a name when you create a widget, using the name parameter. You can then use str to get the name.

For example:

>>> import Tkinter as tk
>>> root = tk.Tk()
>>> f = tk.Frame(root, name="foo")
>>> b1 = tk.Button(f, name="b1")
>>> str(b1)
'.foo.b1'
>>> root.nametowidget(".foo.b1")
<Tkinter.Button instance at 0x100795488>
>>> b1
<Tkinter.Button instance at 0x100795488>
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • Hey Bryan, sorry for the late reply. Thank you very much for the answer but in my case I need to append some sort a value to a dictionary that is bound to the widget. I appreciate that this may not be possible and i may need to give it such a value, and I tried your suggestion, but even the value returned by the name changes, apart from the name of course. Though this means I wouldn't know ahead of time the length of the substring i'd need to slice to obtain the name assigned to the widget. Once again though, thank you for your time :) – Jim Jam May 03 '15 at 07:10
-1

You can create a child class of any widget with an ID, for example:

class labelID(Label):
    def __init__(self,master):
        Label.__init__(self,master)
        self.id = 0

then you can assign a number when create an instance:

my_label = LabelID(root)
my_label.id = 85