Q:

Change position of label in Tkinter window

I am writing a simple program that pulls up an image (BackgroundFinal.png) and displays it in a window. I want to be able to press a button on the window to move the picture down by 22 pixels. Everything works except the button does not do anything. 
import Tkinter
import Image, ImageTk
from Tkinter import Button

a = 0       #sets inital global 'a' and 'b' values
b = 0

def movedown():             #changes global 'b' value (adding 22)
    globals()[b] = 22
    return

def window():               #creates a window 
    window = Tkinter.Tk();
    window.geometry('704x528+100+100');

    image = Image.open('BackgroundFinal.png');      #gets image (also changes image size)
    image = image.resize((704, 528));
    imageFinal = ImageTk.PhotoImage(image);

    label = Tkinter.Label(window, image = imageFinal);   #creates label for image on window 
    label.pack();
    label.place(x = a, y = b);      #sets location of label/image using variables 'a' and 'b'

    buttonup = Button(window, text = 'down', width = 5, command = movedown()); #creates button which is runs movedown()
    buttonup.pack(side='bottom', padx = 5, pady = 5);

    window.mainloop();

window()

If I am not mistaken, the button should change the global 'b' value, therefore changing the y position of the label. I really appreciate any help, sorry for my god-awful conventions. Thanks in advance!

A:

You have a few problems here.  
First, you're using pack and place.  In general, you should only use 1 geometry manager within a container widget.  I don't recommend using place.  That's just too much work that you need to manage.
Second, you're calling the callback movedown when you construct your button.  That's not what you want to do -- You want to pass the function, not the result of the function:
buttonup = Button(window, text = 'down', width = 5, command = movedown)

Third, globals returns a dictionary of the current namespace -- It's not likely to have an integer key in it.  To get the reference to the object referenced by b, you'd need globals()["b"].  Even if it did, changing the value of b in the global namespace won't change the position of your label because the label has no way of knowing that change.  And in general, if you need to use globals, you probably need to rethink your design.
Here's a simple example of how I would do it...
import Tkinter as tk

def window(root):
    buf_frame = tk.Frame(root,height=0)
    buf_frame.pack(side='top')
    label = tk.Label(root,text="Hello World")
    label.pack(side='top')
    def movedown():
        buf_frame.config(height=buf_frame['height']+22)

    button = tk.Button(root,text='Push',command=movedown)
    button.pack(side='top')

root = tk.Tk()
window(root)
root.mainloop()

A:

Thanks for the reply but, It was not really what I was looking for. I'll post what I found worked best here for anybody else with the same problem. 
Essentially, It is much better, in this case, to use a Canvas instead of a label. With canvases, you can move objects with canvas.move, here is a simple example program 
# Python 2
from Tkinter import *

# For Python 3 use:
#from tkinter import *

root = Tk()
root.geometry('500x500+100+100')

image1 = PhotoImage(file = 'Image.gif')

canvas = Canvas(root, width = 500, height = 400, bg = 'white')
canvas.pack()
imageFinal = canvas.create_image(300, 300, image = image1)

def move():
    canvas.move(imageFinal, 0, 22)  
    canvas.update()

button = Button(text = 'move', height = 3, width = 10, command = move)
button.pack(side = 'bottom', padx = 5, pady = 5)

root.mainloop()

my code may not be perfect (sorry!) but that is the basic idea. Hope I help anybody else with this problem 

