Thanks to lots of people's help, I made an tkinter UI that drag/drop the cards.
However, I met another big problem. I want to bind the specific cards using line, but the binding does not work correctly when the number of line is larger than 8.
import tkinter as tk
import tkinter.ttk as ttk
from PIL import ImageTk as itk
window = tk.Tk()
window.state('zoomed')
class DragAndDropArea(tk.Canvas):
def __init__(self,master, **kwargs):
tk.Canvas.__init__(self,master, **kwargs)
self.active = None
head = self.draw_card(200,200, 15,15, 'red1')
eye_r = self.draw_card(220,200, 15,15, 'red2')
eye_l = self.draw_card(180,200, 15,15, 'red3')
neck = self.draw_card(200,250, 15,15, 'orange1')
shoulder_r = self.draw_card(230,260, 15,15, 'orange2')
shoulder_l = self.draw_card(170,260, 15,15, 'orange3')
spine = self.draw_card(200,320, 15,15, 'orange4')
pelvis_l = self.draw_card(180,390, 15,15, 'wheat1')
pelvis_r = self.draw_card(220,390, 15,15, 'wheat2')
elbow_r = self.draw_card(240,330, 15,15, 'yellow1')
wrist_r = self.draw_card(240,400, 15,15, 'yellow2')
fingertip_r = self.draw_card(250,430, 15,15, 'yellow3')
elbow_l = self.draw_card(160,330, 15,15, 'green1')
wrist_l = self.draw_card(160,400, 15,15, 'green2')
fingertip_l = self.draw_card(150,430, 15,15, 'green3')
knee_l = self.draw_card(180,490, 15,15, 'blue1')
ankle_l = self.draw_card(180,560, 15,15, 'blue2')
toe_l = self.draw_card(150,560, 15,15, 'blue3')
knee_r = self.draw_card(220,490, 15,15, 'purple1')
ankle_r = self.draw_card(220,560, 15,15, 'purple2')
toe_r = self.draw_card(250,560, 15,15, 'purple3')
self.bind_tention(head,eye_l)
self.bind_tention(head,eye_r)
self.bind_tention(head,neck)
self.bind_tention(shoulder_l,neck)
self.bind_tention(shoulder_r,neck)
self.bind_tention(spine,neck)
self.bind_tention(spine,pelvis_l)
self.bind_tention(spine,pelvis_r)
#self.bind_tention(shoulder_l,elbow_l)
#self.bind_tention(elbow_l,wrist_l)
#self.bind_tention(wrist_l,fingertip_l)
#self.bind_tention(shoulder_r,elbow_r)
#self.bind_tention(fingertip_r,wrist_r)
#self.bind_tention(elbow_r,wrist_r)
self.bind('<ButtonPress-1>', self.get_item)
self.bind('<B1-Motion>',self.move_active)
self.bind('<ButtonRelease-1>', self.set_none)
def set_none(self,event):
self.active = None
def get_item(self,event):
try:
item = self.find_withtag('current')
print(item)
self.active = item[0]
except IndexError:
pass
#print('no item was clicked')
def move_active(self,event):
if self.active != None:
coords = self.coords(self.active)
width = coords[2] - coords[0] #x2-x1
height= coords[1] - coords[3] #y1-y2
position = coords[0],coords[1]#x1,y1
x1 = event.x - width/2
y1 = event.y - height/2
x2 = event.x + width/2
y2 = event.y + height/2
self.coords(self.active, x1,y1, x2,y2)
try:
self.update_tention(self.active)
except IndexError:
pass
# print('no tentions found')
def update_tention(self, tag):
tentions = self.find_withtag(f'card {tag}')
for tention in tentions:
bounded_cards = self.gettags(tention)
card = bounded_cards[0][-1]
card2= bounded_cards[1][-1]
x1,y1 = self.get_mid_point(card)
x2,y2 = self.get_mid_point(card2)
self.coords(tention, x1,y1, x2,y2)
self.lower(tention)
def draw_card(self, x,y, width,height, color):
x1,y1 = x,y
x2,y2 = x+width,y+height
reference = self.create_rectangle(x1,y1,x2,y2,
fill = color)
return reference
def bind_tention(self, card, another_card):
x1,y1 = self.get_mid_point(card)
x2,y2 = self.get_mid_point(another_card)
tag_I = f'card {card}'
tag_II= f'card {another_card}'
reference = self.create_line(x1,y1,x2,y2, fill='black',
tags=(tag_I,tag_II))
self.lower(reference)
def bind_tention2(self, card, another_card):
x1,y1 = self.get_mid_point(card)
x2,y2 = self.get_mid_point(another_card)
tag_I = f'card {card}'
tag_II= f'card {another_card}'
reference = self.create_line(x1,y1,x2,y2, fill='gray',
tags=(tag_I,tag_II))
self.lower(reference)
def get_mid_point(self, card):
width = coords[2] - coords[0] #x2-x1
height= coords[1] - coords[3] #y1-y2
position = coords[0],coords[1]#x1,y1
mid_x = position[0] + width/2
mid_y = position[1] - height/2
return mid_x,mid_y
def load_bg(self,img_route):
img = itk.PhotoImage(file=img_route)
bg= self.create_image(0,0,anchor = tk.NW,image=img)
return bg
img_route = "C:/Users/ISDL_gram/Documents/hpe/3.png"
area = DragAndDropArea(window, bg='white')
#area.load_bg(img_route)
area.pack(fill='both',expand=1)
window.mainloop()
Here, I added # because the binding worked well for 8 tentions. When I drag the card related in #-tagged tention, it only works at initial loading and fails to update correctly. Now I am thinking update_tention works wrongly but I am having difficulty of understanding how the tags work.
I posts the picture how this works when I want to bind everything. Please teach me what to do and thank you very much.
See Question&Answers more detail:os