Alternate Canvas Objects (Tkinter/Python)

vegaseat 3 Tallied Votes 529 Views Share

You can alternately show one of two lines drawn on the Tkinter canvas by simply moving them on and off the canvas screen. This beats a cumbersome create and delete cycle.

''' tk_canvas_move_lines1.py
toggle/alternate two lines on and off the canvas screen
tested with Python27 and Python33  by  vegaseat  11dec2012
'''

try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

class MyApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.title("click the canvas screen")

        # create_canvas(w, h, color)
        self.create_canvas(400, 400)

        # draw_line(self, x1, y1, x2, y2, color, tagname)
        self.line1 = self.draw_line(10, 10, 250, 50)
        # draw another line
        self.line2 = self.draw_line(10, 10, 250, 180)
        # at start move line2 off the canvas screen
        delta = 400
        self.cv.move(self.line2, delta, delta)

    def create_canvas(self, w, h, color='white'):
        # create a canvas to draw on
        self.cv = tk.Canvas(self, width=w, height=h, bg=color)
        self.cv.grid()
        # optional action on canvas click
        self.cv.bind("<Button-1>", self.action)

    def draw_line(self, x1, y1, x2, y2, color=None):
        '''
        draw a line between points x1,y1 and x2,y2
        default color is black
        '''
        return self.cv.create_line(x1, y1, x2, y2, fill=color)

    def action(self, event=None, tog=[0]):
        # toggles between 1=True and 0=False each call
        tog[0] = not tog[0]
        #print(tog[0])  # test
        delta = 400
        if tog[0]:
            # move line1 off the canvas screen and line2 back on
            self.cv.move(self.line1, delta, delta)
            self.cv.move(self.line2, -delta, -delta)
        else:
            # move line2 off the canvas screen and line1 back on
            self.cv.move(self.line2, delta, delta)
            self.cv.move(self.line1, -delta, -delta)
        pass

    def run(self):
        '''get the event mainloop going'''
        self.mainloop()

MyApp().run()