Home>

I assigned an automatically generated tkinter.ttk.Label type variable to the array, and then assigned the automatically generated variable to the array to make it easier to handle later, but somehow the variable assigned to the array It has become a list type

Error message
Traceback (most recent call last):
  File "address here", line 20, in<module>
    gui [i] .pack ()
AttributeError: 'list' object has no attribute 'pack'
Applicable source code
from tkinter import Tk, ttk, PhotoImage
root = Tk ()
img001 = PhotoImage (file = '# Image address here')
# Display test
label = ttk.Label (root, image = img001)
label.pack ()

gui = []
# Automatically generate and assign to array
for i in range (10):
    locals () ["t_% d"% i] = ttk.Label (root, image = img001)
    gui.append (["t_% d"% i])
# Direct display of one of the automatically generated variables
t_5.pack ()
#Type confirmation
print (type (t_5)) # here tkinter.ttk.Label type
print (gui)
print (gui [5])
print (type (gui [5])) # list type here
#Display variables assigned to array
for i in range (10):
    gui [i] .pack () # Error here
Tried

I tried adding locals () in front of the gui array, but I got an invalid syntax error. . I wonder what I should do sweat
Please give me a solution ...

  • Answer # 1

    I think too hard.

    gui.append (ttk.Label (root, image = img001))

    Do not try locals () or dynamic variable name generation, because the code looks bad and immediately causes strange behavior.

  • Answer # 2

    Cause

    Incorrect:gui.append (["t_% d"% i])
    Correct:gui.append (locals () ["t_% d"% i])

    If you write in error, the value that is appended will be a "list with str as element" like["t_0"]. The previous line assignment statement is

    locals () ["t_% d"% i] = ttk.Label (root, image = img001)

    Is it

    ? This is for example when i is 0

    t_0 = ttk.Label (root, image = img001)

    It has the same meaning as described as

    . The value to be added as an element of gui is the left side of this assignment statement, that is, the variablet_0(orlocals () ["t_% d"% i])

    gui.append (t_0)... (A)
    Or
    gui.append (locals () ["t_% d"% i])... (B)

    If you do not write

    , the meaning will change. In the actual code, i is substituted while changing i in the loop, so it is necessary to write (B) instead of (A).

    Personal opinion (dynamic access oflocalvariables by locals)

    Since we want to access multiple instances of Label like "i-th label", we treat it as a list, and such things aslocalvariable through locals (). I think that the following code is sufficient.

    from tkinter import Tk, ttk, PhotoImage
    root = Tk ()
    img001 = PhotoImage (file = 'img001.png')
    gui = []
    # Create multiple labels (and store them as list elements)
    for i in range (10):
        # No need to create local variables t_0, t_1 etc. using locals
        gui.append (ttk.Label (root, image = img001))
    # place all labels stored in list in order
    for i in range (10):
        gui [i] .pack ()
    root.mainloop ()

    Snacks:
    (1) The value type of variable gui is not an array but a list. There is nothing wrong with saying an array, but it is inaccurate.
    (2) In the current code, the gui element is a label. Variable names seem more natural than labels, such as gui.
    (3) Strictly speaking, pack is a function to "place" a widget instead of "display".
    (Since it will be displayed as a result of placement, I will not say it is a mistake)
    (4) The original code uses full-width#to indicate a comment. It may have been the intention to use full-width (?) Consciousness that `` use half-width # will be a headline in the StackOverflow markdown specification '', but inside the markdown for code such as There is no need to worry about it, so please write it in#according to the Python specification. Otherwise, it will be very troublesome for viewers to copy and paste. If you don't rewrite full-width#to half-width#, you will get a syntax error ...


    Addition: I noticed the inadequacy of my answer in the comment section of hayataka2049's answer.
    Dynamic creation of local variables is not possible withlocals () [variable name] = value.
    However, if you uselocals ()in the global scope, the result is a dict object that represents the global variable namespace (and the global variable namespace is the responsibility of the dict object itself). Dynamic generation of is possible. But in the first placelocals () [variable name] = valueshould be used instead ofglobals () [variable name] = valuethink. In any case, the necessity of using "dynamic generation of variables" is as it was commented in the first answer that it is not necessary in this case.