example code sought

Walter S. Leipold leipoldw at ace-net.com
Mon Dec 20 00:39:48 CET 2004


Sean McIlroy wrote:
> What I want to do is simply to move a shape around on 
> the screen using the mouse. I've looked at Tkdnd.py but 
> I can't seem to extract what I need from the more involved 
> stuff in there.

Here's a simple sample that displays random rectangles that can be dragged
around a Canvas:

=-=-=-=-=-=-=-=-=-=

#!/usr/bin/python
# dsimp.py -- test object dragging

import sys
import math
import Tkinter
import random

class DragCanvas(Tkinter.Frame):
    """A canvas containing 'nrect' random draggable rectangles."""
    tilecolors = (
        "cyan", "gold", "lightgreen", "green",
        "darkgreen", "lightblue", "blue",
        "darkblue", "pink", "red",
        )

    def __init__(self,master,nrect=1):
        """Create the Canvas and a bunch of rectangles."""
        Tkinter.Frame.__init__(self,master)
        self.bbox = (0,0,600,400)
        self.master = master
        self.nrect = nrect
        self.rand = random.Random()
        self.dragging = 0
        self.item = -1
        self.xbase = 0
        self.ybase = 0

        self.xscroll = Tkinter.Scrollbar(self,
            orient=Tkinter.HORIZONTAL)
        self.yscroll = Tkinter.Scrollbar(self,
            orient=Tkinter.VERTICAL)
        self.xscroll.pack(side=Tkinter.BOTTOM,fill=Tkinter.X)
        self.yscroll.pack(side=Tkinter.RIGHT,fill=Tkinter.Y)

        self.world = Tkinter.Canvas(self,
            width=self.bbox[2],
            height=self.bbox[3],
            xscrollcommand=self.xscroll.set,
            yscrollcommand=self.yscroll.set,
            borderwidth=1,
            relief=Tkinter.GROOVE)

        self.xscroll.config(command=self.world.xview)
        self.yscroll.config(command=self.world.yview)

        self.world.pack(fill=Tkinter.BOTH)

        # Mouse commands for this view.
        self.world.bind("<Button-1>",self.__doimageClick)
        self.world.bind("<ButtonRelease-1>",self.__doimageUnclick)
        self.world.bind("<B1-Motion>",self.__doimageDrag)

        for i in range(0,self.nrect):
            # Compute graphics coordinates of tile.
            # (Note first row/col offset by 1 pixel from top/left.)
            xsize = self.rand.randrange(30,80)
            ysize = self.rand.randrange(20,50)
            x1 = self.rand.randrange(0,360)
            y1 = self.rand.randrange(0,260)
            # Create a random rectangle.
            rectnum = self.world.create_rectangle(
                x1,y1,x1+xsize,y1+ysize,
                fill=self.rand.choice(DragCanvas.tilecolors))

        # Limit scrolling in the view.
        #self.world.config(scrollregion=self.world.bbox(Tkinter.ALL))
        self.world.config(scrollregion=self.bbox)

    def __doimageClick(self,event):
        """User clicked mouse; start dragging if item found."""
        x = self.world.canvasx(event.x)
        y = self.world.canvasy(event.y)
        items = self.world.find_overlapping(x-2,y-2,x+2,y+2)
        if len(items) > 0:
            self.dragging = 1
            self.item = items[-1] # Topmost item is returned last.
            self.xbase = x
            self.ybase = y

    def __doimageUnclick(self,event):
        """User released mouse; stop dragging."""
        self.dragging = 0
        self.item = -1

    def __doimageDrag(self,event):
        """Drag an item around the map."""
        if not self.dragging:
            return
        x = self.world.canvasx(event.x)
        y = self.world.canvasy(event.y)
        self.world.move(self.item,x-self.xbase,y-self.ybase)
        self.xbase = x
        self.ybase = y


def doexit():
    """Exit the program, discarding changes."""
    sys.exit(0)


root = Tkinter.Tk()
root.geometry("400x300")
root.title("Draggable?")

mbar = Tkinter.Menu(root)
root.config(menu=mbar)
filemenu = Tkinter.Menu(mbar)
mbar.add_cascade(label="File",menu=filemenu)
filemenu.add_separator()
filemenu.add_command(label="Exit",command=doexit)

worldview = DragCanvas(root,12)
worldview.pack()
root.mainloop()




More information about the Python-list mailing list