Skip to content

tkinter widget instance name sometimes duplicated on inherited class #128562

Description

@philrich123

Bug report

Bug description:

If you run de following code:

import tkinter as tk

class Label2(tk.Label):
     def __init__(self, top, text):
         tk.Label.__init__(self, top, text=text, bg='Yellow')

w = tk.Tk()
w.columnconfigure((0, 1, 2), weight=1, uniform='u1')

label_1 = tk.Label(w, text='Native Label\nInstance 1', bg='LightGreen')
label_1.grid(column=0, row=0)
label_2 = Label2(w, text='Label2 Label\nInstance 1')
label_2.grid(column=1, row=0)
label_3 = tk.Label(w, text='Native Label\nInstance 2', bg='LightGreen')
label_3.grid(column=2, row=0)
w.mainloop()

It will produce the following result (only label_1 and label_3 seems to be placed) :
result

instead of what you expect (the following result) :
expected

Note: This code is using Label for simplicity but it's the same with other widgets !

Explanation:
This is because of automatic generated tkinter widget names:
label_1 name is '.!label'
label_2 name is '.!label2'
label_3 name is '.!label2'

So 'label_2' and 'label_3' has the same widget name.
If you print the 'w.winfo_children()' function just before the 'w.mainloop()', you just get 2 widgets in the list.
The 'label_3' override the 'label_2' because for tkinter they are the same !

To get around this bug:

  • you should not name your class by simply adding a number (like '2' or '3' ...)
  • or you must give a unique name of your class instance with the 'name=' option in the Label constructor.

To correct the bug:
The naming algorithm should check that the automatically generated name is not already in use.

CPython versions tested on:

3.9, 3.13

Operating systems tested on:

Linux, Windows

Linked PRs

Activity

  1. Xiaokang2022 commented on Jan 8, 2025

    @Xiaokang2022
    Contributor

    Hello @philrich123 , I've created a PR to try to fix this. It works for the example you mentioned above, but I don't currently guarantee that it will solve all similar problems, as it may have some omissions.

    In the original code, name only gets the __name__ of the __class__ corresponding to the current instance, not the name of the widgets in tkinter, which can be corrected to avoid the above problem.

  2. added a commit that references this issue on Jan 13, 2025
  3. added 2 commits that reference this issue on Jan 13, 2025
  4. added 2 commits that reference this issue on Jan 13, 2025
  5. serhiy-storchaka commented on Jan 13, 2025

    @serhiy-storchaka
    Member

    Thanks @philrich123 for the report and @Xiaokang2022 for the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-tkintertype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions