Description
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) :
instead of what you expect (the following result) :
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