[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1
control to the GUI event loop—any new requests that arrive during a move are
deferred. Because of that, canvas.update must be called to redraw the screen after
each move, or else updates don’t appear until the entire movement loop callback
finishes and returns. This is a classic long-running callback scenario; without man-
ual update calls, no new GUI events are handled until the callback returns in this
scheme (including both new user requests and basic window redraws).


  • By using the widget.after method to schedule multiple move operations to occur
    every few milliseconds. Because this approach is based upon scheduled events dis-
    patched by tkinter to your handlers, it allows multiple moves to occur in parallel
    and doesn’t require canvas.update calls. You rely on the event loop to run moves,
    so there’s no reason for sleep pauses, and the GUI is not blocked while moves are
    in progress.

  • By using threads to run multiple copies of the time.sleep pausing loops of the first
    approach. Because threads run in parallel, a sleep in any thread blocks neither the
    GUI nor other motion threads. As described earlier, GUIs should not be updated
    from spawned threads in general, but some canvas calls such as move seem to be
    thread-safe today in the current tkinter implementation.


Of these three schemes, the first yields the smoothest animations but makes other
operations sluggish during movement, the second seems to yield slower motion than
the others but is safer than using threads in general, and the second and third allow
multiple objects to be in motion at the same time.


Using time.sleep loops


The next three sections demonstrate the code structure of all three approaches in turn,
with new subclasses of the canvasDraw example we met in Example 9-16 earlier in this
chapter. Refer back to that example for its other event bindings and basic draw, move,
and clear operations; here, we customize its object creators for tags and add new event
bindings and actions. Example 9-30 illustrates the first approach.


Example 9-30. PP4E\Gui\Tour\canvasDraw_tags.py


"""
add tagged moves with time.sleep (not widget.after or threads);
time.sleep does not block the GUI event loop while pausing, but screen not redrawn
until callback returns or widget.update call; currently running onMove callback has
exclusive attention until it returns: others pause if press 'r' or 'o' during move;
"""


from tkinter import *
import canvasDraw, time


class CanvasEventsDemo(canvasDraw.CanvasEventsDemo):
def init(self, parent=None):
canvasDraw.CanvasEventsDemo.init(self, parent)
self.canvas.create_text(100, 10, text='Press o and r to move shapes')
self.canvas.master.bind('', self.onMoveOvals)


Time Tools, Threads, and Animation | 589
Free download pdf