canvasevents.py :  » Language-Interface » ChinesePython » chinesepython2.1.3-0.4 » Demo » tkinter » guido » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Language Interface » ChinesePython 
ChinesePython » chinesepython2.1.3 0.4 » Demo » tkinter » guido » canvasevents.py
#! /usr/bin/env python

from Tkinter import *
from Canvas import Oval,Group,CanvasText


# Fix a bug in Canvas.Group as distributed in Python 1.4.  The
# distributed bind() method is broken.  This is what should be used:

class Group(Group):
    def bind(self, sequence=None, command=None):
  return self.canvas.tag_bind(self.id, sequence, command)

class Object:

    """Base class for composite graphical objects.

    Objects belong to a canvas, and can be moved around on the canvas.
    They also belong to at most one ``pile'' of objects, and can be
    transferred between piles (or removed from their pile).

    Objects have a canonical ``x, y'' position which is moved when the
    object is moved.  Where the object is relative to this position
    depends on the object; for simple objects, it may be their center.

    Objects have mouse sensitivity.  They can be clicked, dragged and
    double-clicked.  The behavior may actually determined by the pile
    they are in.

    All instance attributes are public since the derived class may
    need them.

    """

    def __init__(self, canvas, x=0, y=0, fill='red', text='object'):
  self.canvas = canvas
  self.x = x
  self.y = y
  self.pile = None
  self.group = Group(self.canvas)
  self.createitems(fill, text)

    def __str__(self):
  return str(self.group)

    def createitems(self, fill, text):
  self.__oval = Oval(self.canvas,
         self.x-20, self.y-10, self.x+20, self.y+10,
         fill=fill, width=3)
  self.group.addtag_withtag(self.__oval)
  self.__text = CanvasText(self.canvas,
         self.x, self.y, text=text)
  self.group.addtag_withtag(self.__text)

    def moveby(self, dx, dy):
  if dx == dy == 0:
      return
  self.group.move(dx, dy)
  self.x = self.x + dx
  self.y = self.y + dy

    def moveto(self, x, y):
  self.moveby(x - self.x, y - self.y)

    def transfer(self, pile):
  if self.pile:
      self.pile.delete(self)
      self.pile = None
  self.pile = pile
  if self.pile:
      self.pile.add(self)

    def tkraise(self):
  self.group.tkraise()


class Bottom(Object):

    """An object to serve as the bottom of a pile."""

    def createitems(self, *args):
  self.__oval = Oval(self.canvas,
         self.x-20, self.y-10, self.x+20, self.y+10,
         fill='gray', outline='')
  self.group.addtag_withtag(self.__oval)


class Pile:

    """A group of graphical objects."""

    def __init__(self, canvas, x, y, tag=None):
  self.canvas = canvas
  self.x = x
  self.y = y
  self.objects = []
  self.bottom = Bottom(self.canvas, self.x, self.y)
  self.group = Group(self.canvas, tag=tag)
  self.group.addtag_withtag(self.bottom.group)
  self.bindhandlers()

    def bindhandlers(self):
  self.group.bind('<1>', self.clickhandler)
   self.group.bind('<Double-1>', self.doubleclickhandler)

    def add(self, object):
  self.objects.append(object)
  self.group.addtag_withtag(object.group)
  self.position(object)

    def delete(self, object):
  object.group.dtag(self.group)
  self.objects.remove(object)

    def position(self, object):
  object.tkraise()
  i = self.objects.index(object)
  object.moveto(self.x + i*4, self.y + i*8)

    def clickhandler(self, event):
  pass

    def doubleclickhandler(self, event):
  pass


class MovingPile(Pile):

    def bindhandlers(self):
  Pile.bindhandlers(self)
  self.group.bind('<B1-Motion>', self.motionhandler)
  self.group.bind('<ButtonRelease-1>', self.releasehandler)

    movethis = None

    def clickhandler(self, event):
  tags = self.canvas.gettags('current')
  for i in range(len(self.objects)):
      o = self.objects[i]
      if o.group.tag in tags:
    break
  else:
      self.movethis = None
      return
  self.movethis = self.objects[i:]
  for o in self.movethis:
      o.tkraise()
  self.lastx = event.x
  self.lasty = event.y

    doubleclickhandler = clickhandler

    def motionhandler(self, event):
  if not self.movethis:
      return
  dx = event.x - self.lastx
  dy = event.y - self.lasty
  self.lastx = event.x
  self.lasty = event.y
  for o in self.movethis:
      o.moveby(dx, dy)

    def releasehandler(self, event):
  objects = self.movethis
  if not objects:
      return
  self.movethis = None
  self.finishmove(objects)

    def finishmove(self, objects):
  for o in objects:
      self.position(o)


class Pile1(MovingPile):

    x = 50
    y = 50
    tag = 'p1'

    def __init__(self, demo):
  self.demo = demo
  MovingPile.__init__(self, self.demo.canvas, self.x, self.y, self.tag)

    def doubleclickhandler(self, event):
  try:
      o = self.objects[-1]
  except IndexError:
      return
  o.transfer(self.other())
  MovingPile.doubleclickhandler(self, event)

    def other(self):
  return self.demo.p2

    def finishmove(self, objects):
  o = objects[0]
  p = self.other()
  x, y = o.x, o.y
  if (x-p.x)**2 + (y-p.y)**2 < (x-self.x)**2 + (y-self.y)**2:
      for o in objects:
    o.transfer(p)
  else:
      MovingPile.finishmove(self, objects)

class Pile2(Pile1):

    x = 150
    y = 50
    tag = 'p2'

    def other(self):
  return self.demo.p1


class Demo:

    def __init__(self, master):
  self.master = master
  self.canvas = Canvas(master,
           width=200, height=200,
           background='yellow',
           relief=SUNKEN, borderwidth=2)
  self.canvas.pack(expand=1, fill=BOTH)
  self.p1 = Pile1(self)
  self.p2 = Pile2(self)
  o1 = Object(self.canvas, fill='red', text='o1')
  o2 = Object(self.canvas, fill='green', text='o2')
  o3 = Object(self.canvas, fill='light blue', text='o3')
  o1.transfer(self.p1)
  o2.transfer(self.p1)
  o3.transfer(self.p2)


# Main function, run when invoked as a stand-alone Python program.

def main():
    root = Tk()
    demo = Demo(root)
    root.protocol('WM_DELETE_WINDOW', root.quit)
    root.mainloop()

if __name__ == '__main__':
    main()
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.