I have a label with many child labels, I want it to be draggable so the user can drag it anywhere they want in the parent label space (size x y). Long search but I did not find any. i found tkinterDnD but when i try pip3 to install thinterDnD for python3 it returns an error of no version of it was found. Any help is appreciated
CodePudding user response:
I would sugest that you use widget.bind("<B1-Motion>", function)
and inside the function use widget.config(width=)
. These are built in functions no new modules needed. Also you could use widget.pack_forget()
with widget.pack(pady=, padx=)
.
CodePudding user response:
You can use place
to place a label inside another label at a specific coordinate. To support dragging an item you just need to bind on a button click and button motion to adjust the coordinate.
Here's one way to do it. This example uses a label as a container, but you can use any widget you want since tkinter allows any widget to be the parent of another widget. That being said, using a Label
is an odd choice for a container of other widgets. A Frame
would make more sense.
import tkinter as tk
class Draggable():
def __init__(self, widget, x=0, y=0):
self.start_x = 0
self.start_y = 0
widget.place(x=x, y=y)
widget.bind("<ButtonPress-1>", self.drag_start)
widget.bind("<B1-Motion>", self.drag)
def drag_start(self, event):
self.start_x = event.x
self.start_y = event.y
def drag(self, event):
delta_x = event.x - self.start_x
delta_y = event.y - self.start_y
# move the widget to the new position
x = event.widget.winfo_x() delta_x
y = event.widget.winfo_y() delta_y
event.widget.place(x=x, y=y)
root = tk.Tk()
root.geometry("400x400")
container = tk.Label(root, bd=2, relief="raised")
container.pack(side="top", fill="both", expand=True, padx=20, pady=20)
l1 = tk.Label(container, text="Label #1")
l2 = tk.Label(container, text="Label #2")
Draggable(l1, x=10, y=10)
Draggable(l2, x=10, y=30)
root.mainloop()