# File: aniwave.py # http://infohost.nmt.edu/tcc/help/pubs/tkinter//canvas.html#create_line from tkinter import * from tkinter import ttk from demopanels import MsgPanel, SeeDismissPanel class AnimatedWaveDemo(ttk.Frame): def __init__(self, isapp=True, name='aniwavedemo'): ttk.Frame.__init__(self, name=name) self.pack(expand=Y, fill=BOTH) self.master.title('Animated Wave Demo') self.isapp = isapp self._create_widgets() def _create_widgets(self): if self.isapp: MsgPanel(self, ["This demonstration contains a canvas widget with a line item ", "inside it. The animation routines work by adjusting the ", "coordinates list of the line; which, in turn, changes the ", "position of the frequency zig-zag on the line."]) SeeDismissPanel(self) self._create_demo_panel() def _create_demo_panel(self): demoPanel = Frame(self) demoPanel.pack(side=TOP, fill=BOTH, expand=Y) # Create a canvas large enough to hold the wave. In fact, the wave # sticks off both sides of the canvas to prevent visual glitches. self.__canvas = Canvas(demoPanel, width=300, height=200, background='black') self.__canvas.pack(padx=10, pady=10, expand=Y) # Create a coordinates list for the wave. This code does a very sketchy # job and relies on Tk's line smoothing to make things look better. self.__waveCoords = [] for x in range(-10, 305, 5): self.__waveCoords.extend((x, 100)) # straight line self.__waveCoords.extend((305,0, 310, 200)) # frequency zig-zag # Create a smoothed line using the wave coordinates we've just set self.__canvas.create_line(self.__waveCoords, tags=('wave',), width=1, fill='green', smooth=True) self.__direction = 'left' # set the direction of wave self._move() # start the animation def _move(self): # start the animation self._basic_motion() self._reverse_wave() # repeat the animation every 10 milliseconds self.after(10, self._move) def _basic_motion(self): # Basic motion handler. # Advances the 'y' coordinates of the wave line # one step in the currently active direction. # get a copy of the current wave line coordinates oc = list(self.__waveCoords) oclen = len(oc) for i in range(1, oclen, 2): if self.__direction == 'left': idx = i + 2 # at a boundary? if idx > oclen: idx = 1 self.__waveCoords[i] = oc[idx] else: # moving 'right' idx = i - 2 # at a boundary? if idx < 0: idx = oclen-1 self.__waveCoords[i] = oc[idx] # redraw the wave line self.__canvas.coords('wave', *self.__waveCoords) def _reverse_wave(self): # Oscillation handler. This detects whether to reverse the direction # of the wave by checking to see if the peak of the wave (whose size # we already know) has moved off the screen. # get current wave line coordinates wave = self.__canvas.coords('wave') if wave[1] < 10: # first 'y' coord self.__direction = 'right' elif wave[-1] < 10: # last 'y' coord self.__direction = 'left' if __name__ == '__main__': AnimatedWaveDemo().mainloop()
Wednesday, August 29, 2012
Tkinter Animated Wave Demo
This code is based on the Tcl aniwave.tcl demo. A wave frequency line is drawn and animated, moving the frequency peak from right to left and back along the line.
Labels:
Tkinter Animation,
Tkinter Canvas,
Tkinter Demos