简体   繁体   中英

Deactivate the drag-and-drop feature

def drag_and_drop(self):
    """
    Method allowing to drag and drop a pawn
    """
    if self.game.onOff.get() == 1:
       self._drag_data = {"x": 0, "y": 0, "item": None}
       self.tag_bind("piece", "<ButtonPress-1>", self.drag_beg)
       self.tag_bind("piece", "<ButtonRelease-1>", self.drag_end)
       self.tag_bind("piece", "<B1-Motion>", self.drag)
    else:
       do_Something()

def drag_beg(self, event):
    """Begining drag of an object"""
    # record the item and its location
    self._drag_data["item"] = self.find_closest(event.x, event.y)[0]
    self._drag_data["x"] = event.x
    self._drag_data["y"] = event.y

def drag_end(self, event):
    """End drag of an object"""
    # reset the drag information
    self._drag_data["item"] = None
    self._drag_data["x"] = 0
    self._drag_data["y"] = 0

def drag(self, event):
    """Handle dragging of an object"""
    # compute how much the mouse has moved
    delta_x = event.x - self._drag_data["x"]
    delta_y = event.y - self._drag_data["y"]
    # move the object the appropriate amount
    self.move(self._drag_data["item"], delta_x, delta_y)
    # record the new position
    self._drag_data["x"] = event.x
    self._drag_data["y"] = event.y

The code above allows me to drag and drop a pawn in a checkerboard. The drag_and_drop function is associated with a checkbutton (ie with tkinter). When I check the box in my interface, the drag and drop is activated. When I unchecked the box, I would like to bring back the old setup, ie I click once on a case source and I click a second time target case to move the pawn to the new case. I think I have to implement the method do_Something() to deactivate the drag-and-drop feature? How can I do that?

When I check the box, the drag-and-drop is very well activated, but when I unchecked the box, the function drag-and-drop is still activated. I have not found a way to deactivated it.

UPDATE

Can I unbind it this way?

self.tag_bind("piece", "<ButtonPress-1>")
self.tag_bind("piece", "<ButtonRelease-1>")
self.tag_bind("piece", "<B1-Motion>")

There are several ways of switching on and off the drag and drop feature.

  1. As asked by the OP, it is possible to unbind the tag bindings: The use of tag_unbind is pretty straightforward: .tag_unbind(<tag>, <sequence>) will unbind all bindings to the given sequence for items with given tag. In this case:

     def drag_and_drop(self): """ Method allowing to drag and drop a pawn """ if self.game.onOff.get() == 1: self._drag_data = {"x": 0, "y": 0, "item": None} self.tag_bind("piece", "<ButtonPress-1>", self.drag_beg) self.tag_bind("piece", "<ButtonRelease-1>", self.drag_end) self.tag_bind("piece", "<B1-Motion>", self.drag) else: self.tag_unbind("piece", "<ButtonPress-1>") self.tag_unbind("piece", "<ButtonRelease-1>") self.tag_unbind("piece", "<B1-Motion>")

    Below is a full example:

     import tkinter as tk class Board(tk.Canvas): def __init__(self, master, drag_enabled, **kw): tk.Canvas.__init__(self, master, **kw) self.drag_enabled = drag_enabled self._drag_data = {"x": 0, "y": 0, "item": None} self.create_oval(10, 10, 50, 50, fill='white', tags='piece') def drag_and_drop(self): """ Method allowing to drag and drop a pawn """ if self.drag_enabled.get(): self._drag_data = {"x": 0, "y": 0, "item": None} self.tag_bind("piece", "<ButtonPress-1>", self.drag_beg) self.tag_bind("piece", "<ButtonRelease-1>", self.drag_end) self.tag_bind("piece", "<B1-Motion>", self.drag) else: self.tag_unbind("piece", "<ButtonPress-1>") self.tag_unbind("piece", "<ButtonRelease-1>") self.tag_unbind("piece", "<B1-Motion>") def drag_beg(self, event): """Begining drag of an object""" # record the item and its location self._drag_data["item"] = self.find_closest(event.x, event.y)[0] self._drag_data["x"] = event.x self._drag_data["y"] = event.y def drag_end(self, event): """End drag of an object""" # reset the drag information self._drag_data["item"] = None self._drag_data["x"] = 0 self._drag_data["y"] = 0 def drag(self, event): """Handle dragging of an object""" # compute how much the mouse has moved delta_x = event.x - self._drag_data["x"] delta_y = event.y - self._drag_data["y"] # move the object the appropriate amount self.move(self._drag_data["item"], delta_x, delta_y) # record the new position self._drag_data["x"] = event.x self._drag_data["y"] = event.y root = tk.Tk() drag_enabled = tk.BooleanVar(root) board = Board(root, drag_enabled) tk.Checkbutton(root, text='Enable drag', variable=drag_enabled, command=board.drag_and_drop).pack(side='bottom') board.pack() root.mainloop()
  2. As suggested in the comments, it is possible to check whether drag and drop is activated inside the functions called by the bindings and return without doing anything if it is disabled. Something like:

     def <drag function>(self, event): if self.drag_enabled.get(): # drag and drop actions

    In this case, the drag_and_drop() function is not needed and can be put into the initialization of the board:

     import tkinter as tk class Board(tk.Canvas): def __init__(self, master, drag_enabled, **kw): tk.Canvas.__init__(self, master, **kw) self.drag_enabled = drag_enabled self._drag_data = {"x": 0, "y": 0, "item": None} self.create_oval(10, 10, 50, 50, fill='white', tags='piece') self._drag_data = {"x": 0, "y": 0, "item": None} self.tag_bind("piece", "<ButtonPress-1>", self.drag_beg) self.tag_bind("piece", "<ButtonRelease-1>", self.drag_end) self.tag_bind("piece", "<B1-Motion>", self.drag) def drag_beg(self, event): """Begining drag of an object""" # record the item and its location if self.drag_enabled.get(): self._drag_data["item"] = self.find_closest(event.x, event.y)[0] self._drag_data["x"] = event.x self._drag_data["y"] = event.y def drag_end(self, event): """End drag of an object""" # reset the drag information self._drag_data["item"] = None self._drag_data["x"] = 0 self._drag_data["y"] = 0 def drag(self, event): """Handle dragging of an object""" # compute how much the mouse has moved if self.drag_enabled.get(): delta_x = event.x - self._drag_data["x"] delta_y = event.y - self._drag_data["y"] # move the object the appropriate amount self.move(self._drag_data["item"], delta_x, delta_y) # record the new position self._drag_data["x"] = event.x self._drag_data["y"] = event.y root = tk.Tk() drag_enabled = tk.BooleanVar(root) b = Board(root, drag_enabled) tk.Checkbutton(root, text='Enable drag', variable=drag_enabled).pack(side='bottom') b.pack(fill='both', expand=True) root.mainloop()

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