# NOTE: see canvas drawing demo in Tour (old movingpics1.py) # # mention that looks best in maximized/fullscreen mode; # canvas expands to fill entire window; # doesn't work: # canvas.focus() # canvas.bind('', self.onKeyboard) # change type # does work: # parent.bind('', self.onKeyboard) # change type # ==> see bind_all note in calculator.py # # ??? fails if other events during move # Units = number units to move after each movedelay # Delay = seconds between moves (0.01 = one hundred times per second) # note: can move info text around too--another kind of object # canvas commands accept object ids or tags; note raise => tkraise # note that can resize and maximize canvas--grows with the window # note the phots inserted at last coordinates (click left 1st to pick spot) # ??? do move in a thread? # ??? rewrite to be more object-based? (sigle 'current' object/where # model doesn't support threads well (moving > 1 in parallel); # BUT: would need to use locks to prevent an object being moved # from being selected and moved again, while current move in progress; # AND: eanch image would need a lock to prevent deletes while moving, # drages while moving, etc. # # explain why need 'lambda self' in key table for thnigs without # ags--uniformity (1st few specify args to be passed, so lambda # needed to delay calls; to call all with 'self' all must use # lambda; alt = self.fill in table, and def fill(self, dummy)) # changed: use defaults for self entries, instead of passing in # self via keymap[event.char](self) and lambda self: self.method(); # but since defaults are demod in other guis, used last of these # 4 ways to code: # keymap[event.char](self) and lambda self: self.method() for all # keymap[event.char](self) and def method(self, dummy) for some # keymap[event.char]() and lambda s=self: s.method() for some # * keymap[event.char](self) and MovingPics.method unbound meth for some # # image open pattern # fixed # some things can happen during move; list of moving objects? # fixed: can now drag and grow while move in progress # can start another move but it makes curent move sleep until # 2nd move is finished # # note: changing speed during a move changes velocity of the # move--reads global pickDelays each time through for loops # # mention postscript file save option # # def onGrow(self, event): # # varies by object type and pen style # # elastic: delete and redraw from start point to here # # scribble: draw again from last stop point to here # # trails: redraw again from start point, no delete # caveat: in scribble and trails mode, object = last segment only thread version notes... to try: start this modules, maximize screen, draw a few # objects on the left edge of canvas (or load pics), pick # one (middle) and move to right edge (left), then pick rest # and start moves to right while other moves in progress; # they all move at the same time, since move is implemented # as a thread; # # note need for mutex: more than one thread may be updating # the self.moving list at same time--thread share global # memory, and self attrs are global to threads (i.e., # not local to thread func); python vm switches threads # every few virtual macine ops--things like append and # remove are not necesarily atomic??? # # original movingpics.py allows > 1 move to be started, # but only one is ever moving at a time; startin a new # move suspends the one in progress till new move finishes; # # works on Linux??? # _does_ work on MS-Windows 98, provided the canvas.update() # calls are not run (else exits with fatal errors, some objs # start moving immediately after drawn, etc.) # # on win98 before mutex and update() calls disabled--object # moves start veering to follow the mouse # # suggested exercise: add binding for button-3 double click # in init, which animates the current object: e.g.,move it # left anf right a finite number of times; need to add to # self.moving list, so not moved by > 1 thread at once; self.canvas.bind('', self.onAnimate) # double right click def onAnimate(self, event): object = self.object if object and object not in self.moving: self.mutex.acquire() self.moving.append(object) self.mutex.release() thread.start_new_thread( self.doAnimate, (self.canvas, object)) def doAnimate(self, canvas, object): for i in range(1000): canvas.move(object, random.choice(range(-10,10)), random.choice(range(-10,10))) time.sleep(pickDelays[0]) self.mutex.acquire() self.moving.remove(object) self.mutex.release() ###############################################################