Passing a list to a function in order to move objects in tkinter (python 3)
Question: I am making a rubiks slide game. The first functioning button I am doing is
the clockwise button (every other button does nothing). i have the four
positions of squares set, and put them in a list called board. I then call the
list to the clockwise_move function from the clockwise button, and it is
supposed to move the square in whatever position stated. I cannot understand
why this will no work.

    
    
    from tkinter import *
    from tkinter import ttk
    
    # --- Functions ---
    
    def clockwise_move(square):
        canvas.coords(square[0], 500, 2, 250, 250)
        canvas.coords(square[1], 500, 490, 249, 250)
        canvas.coords(square[2], 2, 2, 249, 249)
        canvas.coords(square[3], 2, 490, 249, 250)
    
    
    # --- Setup ---
    
    main = Tk()
    
    main.title("Rubik's Slide")
    main.resizable(width=FALSE, height=FALSE)
    main.geometry("700x550")
    
    # --- Objects ---
    
    frame = ttk.Frame(main)
    button_frame = ttk.Frame(frame)
    canvas = Canvas(frame, width=500, height=700)
    
    
    #squares
    square1 = canvas.create_rectangle(2, 2, 249, 249, fill="red")
    square2 = canvas.create_rectangle(500, 2, 250, 250, fill="white")
    square3 = canvas.create_rectangle(2, 490, 249, 250, fill="blue")
    square4 = canvas.create_rectangle(500, 490, 250, 250, fill="black")
    
    board = [square1,square2,square3,square4]
    
    #buttons
    clockwise = ttk.Button(button_frame, text="Clockwise", command=clockwise_move(board))
    clockwise.grid(column=2, row=3)
    
    counter_clockwise = ttk.Button(button_frame, text="Counterclock")
    counter_clockwise.grid(column=3, row=3)
    
    right = ttk.Button(button_frame, text="Right")
    right.grid(column=2, row=1)
    
    left = ttk.Button(button_frame, text="Left")
    left.grid(column=2, row=2)
    
    up = ttk.Button(button_frame, text="Up")
    up.grid(column=3, row=1)
    
    down = ttk.Button(button_frame, text="Down")
    down.grid(column=3, row=2)
    
    start = ttk.Button(button_frame, text="Start")
    start.grid(column=2, row=4)
    
    reset = ttk.Button(button_frame, text="Reset")
    reset.grid(column=3, row=4)
    
    #frame grid
    frame.grid(column=1, row=1)
    canvas.grid(column=1, row=1)
    button_frame.grid(column=2, row=1)
    
    #misc settings
    for child in button_frame.winfo_children():
        child.grid_configure(padx=10, pady=20)
    
    main.mainloop() #end of GUI
    


Answer: In your line where you assign the command `clockwise_function` onto the
button, your are asigning the result of the function. So the outcome is, that
your function get called after you have started your app without clicking the
button.

The prove this you can simply put a print("Call") into your definition of
`clockwise_function`. Instead you can wrap the function call into a lambda
expression `command=lambda:clockwise_move(board))`. So instead of passing in
the result of the function you are passing in the instance of an anonymous
function.

An alternative would be removing the parameter `square` and using a global
variable.

Without an parameter you would simply:

    
    
    def prototype():
        print("do something")
    
    ... command = prototype # the reference to the function
    

the button click would then act like `command()`

Btw for making things easier you also could save your positions like in a
dictionary, list or Enum:

here I am using an dictionary

    
    
    # Top Left | Top Right | Bottom Left | Bottom Right
    p= {"tr":[500, 2, 250, 250],
        "br":[500, 490, 249, 250],
        "tl":[2, 2, 249, 249],
        "bl":[2, 490, 249, 250]}
    
    def clockwise_move(square):
        canvas.coords(square[0], *p["tr"])
        canvas.coords(square[1], *p["br"])
        canvas.coords(square[2], *p["tl"])
        canvas.coords(square[3], *p["bl"])
    

