These 2 codes are exactly the same, the only difference is that 1 uses tkinter and the other one uses customtkinter
I am wondering how I could make the customtkinter code work. Is there something that I am missing or something I should change for the second code to work?
In the second code the "drag and drop" functions do not work, while in the first code (tkinter), everything works just fine. I have included a side note (#this changed) in the second code, to indentify what are the things that changed.
NOTE: the reason I add the comlete code is because all functions shown are needed for the "drag and drop" to work and I do not know where the mistake is.
See below:
With tkinter:
import tkinter
def changeOrder(widget1,widget2,initial):
target=widget1.grid_info()
widget1.grid(row=initial['row'],column=initial['column'])
widget2.grid(row=target['row'],column=target['column'])
def on_click(event):
widget=event.widget
print(widget)
if isinstance(widget,tkinter.Label):
start=(event.x,event.y)
grid_info=widget.grid_info()
widget.bind("<B1-Motion>",lambda event:drag_motion(event,widget,start))
widget.bind("<ButtonRelease-1>",lambda event:drag_release(event,widget,grid_info))
else:
root.unbind("<ButtonRelease-1>")
def drag_motion(event,widget,start):
x = widget.winfo_x()+event.x-start[0]
y = widget.winfo_y()+event.y-start[1]
widget.lift()
widget.place(x=x,y=y)
def drag_release(event,widget,grid_info):
widget.lower()
x,y=root.winfo_pointerxy()
target_widget=root.winfo_containing(x,y)
if isinstance(target_widget,tkinter.Label):
changeOrder(target_widget,widget,grid_info)
else:
widget.grid(row=grid_info['row'],column=grid_info['column'])
root = tkinter.Tk()
_entry={}
rows=3
columns = 2
for row in range(rows):
for column in range(columns):
index=(row,column)
myTextLabel1 = tkinter.Label(root,text="Label 1",bg='yellow')
myTextLabel1.grid(row=row,column=column,padx=5,pady=5)#sticky=E+W+S+N)
_entry[index] = myTextLabel1
_entry[index].configure(bg='red')
root.bind("<Button-1>",on_click)
root.mainloop()
With Customtkinter:
#WITH CUSTOMTKINTER
import customtkinter
def changeOrder(widget1,widget2,initial):
target=widget1.grid_info()
widget1.grid(row=initial['row'],column=initial['column'])
widget2.grid(row=target['row'],column=target['column'])
def on_click(event):
widget=event.widget
print(widget)
if isinstance(widget,customtkinter.CTkLabel): #this changed
start=(event.x,event.y)
grid_info=widget.grid_info()
widget.bind("<B1-Motion>",lambda event:drag_motion(event,widget,start))
widget.bind("<ButtonRelease-1>",lambda event:drag_release(event,widget,grid_info))
else:
root.unbind("<ButtonRelease-1>")
def drag_motion(event,widget,start):
x = widget.winfo_x()+event.x-start[0]
y = widget.winfo_y()+event.y-start[1]
widget.lift()
widget.place(x=x,y=y)
def drag_release(event,widget,grid_info):
widget.lower()
x,y=root.winfo_pointerxy()
target_widget=root.winfo_containing(x,y)
if isinstance(target_widget,customtkinter.CTkLabel): #this changed
changeOrder(target_widget,widget,grid_info)
else:
widget.grid(row=grid_info['row'],column=grid_info['column'])
root = customtkinter.CTk()
_entry={}
rows=3
columns = 2
for row in range(rows):
for column in range(columns):
index=(row,column)
myTextLabel1 = customtkinter.CTkLabel(root,text="Label 1",bg_color='yellow') #this changed
myTextLabel1.grid(row=row,column=column,padx=5,pady=5)#sticky=E+W+S+N)
_entry[index] = myTextLabel1
_entry[index].configure(bg_color='red') #this changed
root.bind("<Button-1>",on_click)
root.mainloop()
Thank you in advance
Note that customtkinter
widget is basically tkinter.Frame
which contains other tkinter
widgets inside it. For example, customtkinter.CTkLabel
is a tkinter.Frame
containing a tkinter.Canvas
and tkinter.Label
. So clicking on a customtkinter.Label
will either clicking on the internal canvas
or label
based on the position of the mouse cursor actually.
Therefore you need to check the parent of the clicked widget instead and move that parent instead of the clicked widget:
...
def on_click(event):
widget = event.widget
# check widget.master instead
if isinstance(widget.master, customtkinter.CTkLabel): #this changed
start = (event.x, event.y)
# use widget.master instead in below lines
grid_info = widget.master.grid_info()
widget.bind("<B1-Motion>", lambda event:drag_motion(event, widget.master, start))
widget.bind("<ButtonRelease-1>", lambda event:drag_release(event, widget.master, grid_info))
else:
root.unbind("<ButtonRelease-1>")
...
def drag_release(event, widget, grid_info):
widget.lower()
x, y = root.winfo_pointerxy()
target_widget = root.winfo_containing(x, y)
if target_widget.master != widget and isinstance(target_widget.master, customtkinter.CTkLabel): #this changed
changeOrder(target_widget.master, widget, grid_info)
else:
widget.grid(row=grid_info['row'], column=grid_info['column'])
...