tkinter - 布局中的错误

时间:2015-05-24 19:30:10

标签: python canvas layout tkinter label

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

以下是我的代码(代码会导致标有#的问题):

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。

1 个答案:

答案 0 :(得分:1)

The reason the new label doesn't go to the same place as the original label is… well, that's the way the pack geometry manager works: Where something goes depends on what else already exists at the time you pack it. The original label gets packed into an empty space, and then other stuff gets packed after it, so it ends up on top. The new label gets packed into a space that already has that other stuff, so it ends up on the bottom.

You could work around this by just passing the side=BOTTOM argument.

Or you could use a grid layout instead of a pack layout to make sure everything ends up exactly where you want it.

However, I think what you really want here is a lot simpler: instead of repeatedly destroying labels and creating new ones and hoping you can fit them in the same place, just keep the label and change its text.

In other words, instead of this:

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

… just do this:

    # other code
    label.config(text=up_score)

Or, maybe even better, assign a StringVar to the Label, and just call set on that StringVar (as demonstrated in the next-to-last pattern in the Label docs in the Tkinter book).