tkinter - 布局错误

tkinter - mistake in the layout

在下面的代码中,我希望第 34 行的 label 转到我的 canvas 的顶部,就像第 59 行的 label 一样。但它会转到我的 canvas 的底部,即使我在两个地方使用相同的代码。

这是我的代码(导致问题的代码标有 #):

from tkinter import*
from random import*

score = 0

Fenetre = Tk()

def Clavier(event):
    global coords
    global score
    global label

    touche = event.keysym

    if touche == "Up":
        coords = (coords[0], coords[1] - 10)
    elif touche == "Down":
        coords = (coords[0], coords[1] + 10)
    elif touche == "Right":
        coords = (coords[0] + 10, coords[1])
    elif touche == "Left":
        coords = (coords[0] -10, coords[1])

    canvas.coords(eater, coords[0], coords[1], coords[0]+20, coords[1]+20)

    while canvas.bbox(eater) == canvas.bbox(food):
        canvas.delete(food)
        label.destroy()
        global food
        up_score = score
        up_score = up_score + 1
        score = up_score
        label = Label(Fenetre, text = up_score) # line 34
        label.pack()
        X=choice(liste)
        Y=choice(liste)
        food = canvas.create_rectangle(X,Y,X+20,Y+20,fill="grey")

#fond = PhotoImage(file="Moi.gif")

canvas = Canvas(Fenetre, width=189, height=189)
#canvas.create_image(0,0,image=fond,anchor = NW)

coords = (0, 0)

liste_couleur = ["green","white","red","blue","yellow","violet","orange"]
couleur = choice(liste_couleur)
eater = canvas.create_oval(0,0,20,20,fill=couleur)

canvas.focus_set()
canvas.bind("<Key>", Clavier)

liste = [10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180]
X = choice(liste)
Y = choice(liste)
food = canvas.create_rectangle(X,Y,X+20,Y+20,fill="grey")

label = Label(Fenetre, text = score) # line 59

label.pack()
canvas.pack()
Fenetre.mainloop()

如果重要的话,我正在使用 Python 3.2.

新标签与原始标签不同的原因是……好吧,这就是 the pack geometry manager 的工作方式:某物去向取决于您 pack它。原始标签被打包到一个空的 space 中,然后其他内容在它之后被打包,所以它最终在顶部。新标签被打包到一个已经有其他东西的 space 中,所以它最终在底部。

可以通过传递 side=BOTTOM 参数来解决这个问题。

或者您可以使用 grid 布局而不是 pack 布局,以确保所有内容都在您想要的位置结束。

但是,我认为您真正在这里想要的要简单得多:与其反复销毁标签并创建新标签并希望您可以将它们放在同一个地方,只是保留标签并更改其文本。

换句话说,而不是这个:

    label.destroy()
    # other code
    label = Label(Fenetre, text = up_score) # line 34
    label.pack()

…就这样做:

    # other code
    label.config(text=up_score)

或者,也许更好,将 StringVar 分配给 Label,然后在 StringVar 上调用 set(如下所示Tkinter 书中 Label 文档中的最后一个模式。