Python Tkinter drawing App - Freehand drawing and undo
Write a Python program to design a drawing application with Tkinter that allows users to draw freehand on a Canvas widget. Implement an "Undo" button to remove the last drawn line.
Sample Solution:
Python Code:
import tkinter as tk
class DrawingApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Drawing App")
        self.canvas = tk.Canvas(root, bg="white")
        self.canvas.pack(fill=tk.BOTH, expand=True)
        self.pen_color = "black"
        self.drawing = False
        self.last_x, self.last_y = None, None
        self.lines = []  # List to store drawn lines
        self.undo_button = tk.Button(root, text="Undo", command=self.undo)
        self.erase_button = tk.Button(root, text="Erase", command=self.erase)
        
        self.undo_button.pack(side=tk.LEFT)
        self.erase_button.pack(side=tk.LEFT)
        self.canvas.bind("<Button-1>", self.start_draw)
        self.canvas.bind("<B1-Motion>", self.draw)
        self.canvas.bind("<ButtonRelease-1>", self.stop_draw)
    def start_draw(self, event):
        self.drawing = True
        self.last_x, self.last_y = event.x, event.y
    def draw(self, event):
        if self.drawing:
            x, y = event.x, event.y
            line = self.canvas.create_line(self.last_x, self.last_y, x, y, fill=self.pen_color, width=2)
            self.lines.append(line)  # Store the drawn line
            self.last_x, self.last_y = x, y
    def stop_draw(self, event):
        self.drawing = False
    def undo(self):
        if self.lines:
            last_line = self.lines.pop()  # Remove the last drawn line
            self.canvas.delete(last_line)
    def erase(self):
        self.canvas.delete("all")
if __name__ == "__main__":
    root = tk.Tk()
    app = DrawingApp(root)
    root.mainloop()
Explanation:
In the exercise above -
- Import the "tkinter" library.
- "DrawingApp" class represents the main application.
- Initializing the application:
- In the init method, the application's main window (root) is created and titled "Drawing App."
- A Canvas widget is created.
- Setting up initial attributes:
- pen_color: It represents the drawing pen color and is initially set to black.
- drawing: A Boolean variable that keeps track of whether the user is currently drawing.
- last_x and last_y: These variables store the coordinates of the last drawn point.
- lines: A list to store references to the lines drawn on the canvas.
- Creating buttons:
- Two buttons, "Undo" and "Erase," are created using the "Button" widget. The command parameter specifies the functions to be executed when the buttons are clicked.
- The buttons are scattered along the left side of the main window.
- Binding mouse events:
- The Canvas widget is bound to three mouse events:
- <Button-1>: Triggered when the left mouse button is pressed. It calls the start_draw method.
- <B1-Motion>: Triggered when the left mouse button is moved while pressed. It calls the draw method.
- <ButtonRelease-1>: Triggered when the left mouse button is released. It calls the stop_draw method.
- Define event handling methods:
- start_draw(event): Sets the drawing flag to True and records the starting coordinates of the drawing.
- draw(event): Draws lines on the canvas as the mouse is moved. It creates a line object, stores it in the lines list, and updates the last_x and last_y values.
- stop_draw(event): Sets the drawing flag to False when the mouse button is released.
- undo(): Removes the last drawn line by deleting it from the canvas and removing its reference from the lines list.
- erase(): Clears the entire canvas by deleting all elements with the tag "all."
- Finally, start the Tkinter main loop with "root.mainloop()".
Output:
Flowchart:
 
 
Go to:
Previous: Python Tkinter Canvas and Graphics Home.
 Next:  Countdown timer.
Python Code Editor:
What is the difficulty level of this exercise?
Test your Programming skills with w3resource's quiz.

 
