TheFaithfulLearner
TheFaithfulLearner

Reputation: 693

Moving a widget on a canvas in Python

This is about moving a label on a canvas in Python 3.7 (I think) using tkinter.

There are lots of answers on Google and here on this site, but none of them have answered my question and yet I can't imagine my code couldbe much simpler. I'm not terribly experienced when it comes to Python and clearly I'm doing something fundamentally wrong.

What I want to do: move a label to a position on a canvas dictated by the click of a mouse.

Here we are:

root = tk.Tk()
root.geometry("800x600")

def ClickedCallback(event):
    #print(f'Event: {event}, l2: {l2}, tags: {canvas.gettags()}')
    canvas.move(l2, 5, 0)

canvas = tk.Canvas(root, width=1000, height=600, bg='blue')
canvas.bind("<Button-1>", ClickedCallback)
canvas.place(relwidth=0.9, relheight=0.8, relx = 0.05, rely = 0.05)

l2 = tk.Label(canvas, bg='red')
l2.bind("<Button-1>", ClickedCallback)
l2.place(relx=0.2, rely=0.2)
l2['text'] = "Test"

root.mainloop()

Now that causes a straight up error. "line 2591, in move self.tk.call((self._w, 'move') + args) _tkinter.TclError: invalid boolean operator in tag search expression"

I then saw an example that showed the object name entered into the method as a string rather than the object itself. So the line became:

canvas.move('l2', 5, 0)

Now this doesn't cause an error. But it also doesn't do anything.

I don't even know if moving on a canvas is the best way to do this. I just want to move a label around inside the window and this seemed to be the one that appeared in searches.

Upvotes: 0

Views: 837

Answers (1)

furas
furas

Reputation: 142631

To place widget (ie. Label) on Canvas you have to use

label_id = canvas.create_window(position, window=l2,...)

not place()/grid()/pack()

And later you use this label_id to move it.


Simple example - Label is moved when you click Canvas

import tkinter as tk

# --- functions ---

def clicked_callback(event):
    #canvas.move(label_id, 5, 0)
    canvas.coords(label_id, event.x, event.y)

# --- main ---

root = tk.Tk()
root.geometry("800x600")

canvas = tk.Canvas(root, width=1000, height=600, bg='blue')
canvas.bind("<Button-1>", clicked_callback)
canvas.place(relwidth=0.9, relheight=0.8, relx=0.05, rely=0.05)

l2 = tk.Label(canvas, text="Test", bg='red')
#l2.bind("<Button-1>", clicked_callback)
label_id = canvas.create_window((100, 100), window=l2)

root.mainloop()

Upvotes: 3

Related Questions