Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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.

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
118 views
Welcome To Ask or Share your Answers For Others

1 Answer

It is because you get the wrong card ID:

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]  # get only the last digit, e.g. get "3" from "card 13"
        card2= bounded_cards[1][-1]  # get only the last digit
        x1,y1 = self.get_mid_point(card)
        x2,y2 = self.get_mid_point(card2)
        self.coords(tention, x1,y1, x2,y2)
        self.lower(tention)

It should be:

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].split()[-1]  # get last number, e.g. "13" from "card 13"
        card2= bounded_cards[1].split()[-1]  # get last number
        x1,y1 = self.get_mid_point(card)
        x2,y2 = self.get_mid_point(card2)
        self.coords(tention, x1,y1, x2,y2)
        self.lower(tention)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...