简体   繁体   中英

How to fix a widget in a grid row and column while the user is dragging it?

I want a widget which is been dragged by the user to be fixed in a specific grid cell when the widget comes near it, is there any way to do it in tkinter? I managed to make the widget draggable by taking the mouse position of user as he drags the widget, but i dont know how to make it fix into a grid cell.

this is what i use currently to move widgets

def make_draggable(self):
        def drag_start(event):
            widget = self
            widget = event.widget
            self._drag_start_x = event.x
            self._drag_start_y = event.y

        def drag_motion(event):
            widget = self
            widget = event.widget
            x = self.winfo_x() - self._drag_start_x + event.x
            y = self.winfo_y() - self._drag_start_y + event.y
            self.place(x=x, y=y)
        self.bind("<Button-1>", drag_start)
        self.bind("<B1-Motion>", drag_motion)

for example, if the grid cell left top corner position is (x=10,y=10) I need the button to get fixed in the cell when its position is near that value (like 9,9 8,8 9,5 etc)

Based on what I have understood from your question, I have tried the following

from tkinter import *

class Drag:
    def __init__(self,widget):
        self.widget=widget
        self.widget.bind("<Button-1>", self.drag_start)
        self.widget.bind("<B1-Motion>", self.drag_motion)
        self.grid=(100,100)
        self.margin=(20,20)

    def drag_start(self,event):
        self._drag_start_x = event.x
        self._drag_start_y = event.y

    def drag_motion(self,event):
        x = self.widget.winfo_x() - self._drag_start_x + event.x
        y = self.widget.winfo_y() - self._drag_start_y + event.y
        if (
            x%self.grid[0] in range(self.margin[0]) and 
            y%self.grid[1] in range(self.margin[1])
        ):
            self.widget.place(x=x-x%self.grid[0],y=y-y%self.grid[1])
        else:
            self.widget.place(x=x, y=y)

root=Tk()
root.minsize(300,200)

label=Label(root,text='Drag Me',bg='yellow')
label.pack()

Drag(label)

root.mainloop()

This basically creates grid of "cells" of height and width 100 and it clips it to the cell if it is in 20 pixel range of the top left corner of the cell. This is basically done by taking the remainders of the current coordinates when divided by the cell's height/width using the modulo % operator and comparing if this lies in the desired range.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM