Python Project - Basic Drawing App using Tkinter and PyQt5
Basic Drawing App:
Create a simple drawing application with basic shapes and colors.
Input values:
User interacts with the drawing application by selecting drawing tools (pencil, rectangle, etc.), shapes, colors, and making strokes on the canvas.
Output value:
Visual representation of the drawn elements on the canvas, including shapes and colors.
Example:
Input values: 1. Select Pencil tool 2. Select Red color 3. Draw a freehand stroke on the canvas Output value: Canvas displays a Red freehand stroke. Input values: 1. Select Rectangle tool 2. Select Blue color 3. Draw a rectangle on the canvas Output value: Canvas displays a blue rectangle. Input values: 1. Select Eraser tool 2. Erase part of the drawn elements Output value: Canvas displays the erased portion. Input values: 4. Save the drawing to a file Output value: Drawing saved successfully to "my_drawing.png".
Solution 1: Basic Drawing App Using Tkinter
‘Tkinter’ is a popular Python library for creating simple GUI applications. This solution will use Tkinter's ‘Canvas’ widget to draw shapes, freehand strokes, and save the drawing to a file.
Code:
# Solution 1: Basic Drawing App Using Tkinter
import tkinter as tk # Import the Tkinter library for creating GUI applications
from tkinter import colorchooser # Import the colorchooser module to select colors
from tkinter import filedialog # Import the filedialog module to save the drawing
from PIL import Image # Import PIL (Pillow) to handle image saving
# Main class for the Drawing App
class DrawingApp:
"""Class to create a simple drawing application with basic shapes and colors."""
def __init__(self, root):
"""Initialize the DrawingApp with a Tkinter window."""
self.root = root
self.root.title("Basic Drawing App")
# Initialize drawing settings
self.color = "black" # Default color is black
self.tool = "pencil" # Default tool is pencil
self.canvas = tk.Canvas(root, bg="white", width=400, height=300) # Create a canvas for drawing
self.canvas.pack(fill=tk.BOTH, expand=True) # Pack the canvas to fill the window
# Bind mouse events to canvas for drawing
self.canvas.bind("", self.draw) # Bind mouse movement with the left button pressed
self.canvas.bind("", self.start_draw) # Bind mouse button press to start drawing
# Create a toolbar for selecting tools and colors
toolbar = tk.Frame(root, bg="lightgray") # Create a toolbar frame
toolbar.pack(side=tk.TOP, fill=tk.X) # Pack the toolbar at the top
# Add buttons for tools
pencil_btn = tk.Button(toolbar, text="Pencil", command=lambda: self.select_tool("pencil"))
pencil_btn.pack(side=tk.LEFT, padx=2, pady=2)
rect_btn = tk.Button(toolbar, text="Rectangle", command=lambda: self.select_tool("rectangle"))
rect_btn.pack(side=tk.LEFT, padx=2, pady=2)
eraser_btn = tk.Button(toolbar, text="Eraser", command=lambda: self.select_tool("eraser"))
eraser_btn.pack(side=tk.LEFT, padx=2, pady=2)
# Add button for color selection
color_btn = tk.Button(toolbar, text="Color", command=self.choose_color)
color_btn.pack(side=tk.LEFT, padx=2, pady=2)
# Add button for saving the drawing
save_btn = tk.Button(toolbar, text="Save", command=self.save_drawing)
save_btn.pack(side=tk.LEFT, padx=2, pady=2)
self.previous_x = None # Store the previous x-coordinate of the mouse for drawing
self.previous_y = None # Store the previous y-coordinate of the mouse for drawing
def select_tool(self, tool):
"""Select the current drawing tool."""
self.tool = tool
def choose_color(self):
"""Choose a color for drawing."""
self.color = colorchooser.askcolor()[1] # Open the color chooser dialog and store the selected color
def start_draw(self, event):
"""Initialize drawing when the mouse button is pressed."""
self.previous_x, self.previous_y = event.x, event.y # Store the starting coordinates for drawing
def draw(self, event):
"""Draw on the canvas based on the selected tool and mouse movement."""
if self.tool == "pencil":
self.canvas.create_line(self.previous_x, self.previous_y, event.x, event.y, fill=self.color, width=2)
elif self.tool == "rectangle":
self.canvas.create_rectangle(self.previous_x, self.previous_y, event.x, event.y, outline=self.color)
elif self.tool == "eraser":
self.canvas.create_line(self.previous_x, self.previous_y, event.x, event.y, fill="white", width=10)
# Update the previous coordinates to the current coordinates
self.previous_x, self.previous_y = event.x, event.y
def save_drawing(self):
"""Save the drawing to a file."""
filename = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG files", "*.png")])
if filename:
# Save the canvas content to a file
self.canvas.postscript(file="temp.ps", colormode='color')
img = Image.open("temp.ps")
img.save(filename, 'png')
print("Drawing saved successfully to", filename)
# Create the main window
root = tk.Tk()
app = DrawingApp(root)
root.mainloop()
Output:
Explanation:
- Imports:
- tkinter: Used for creating the GUI and handling user interactions.
- colorchooser and filedialog: Used for selecting colors and saving files.
- Pillow (PIL): Used for converting the canvas content to an image file format (e.g., PNG).
- Class DrawingApp:
- __init__: Initializes the drawing application, sets up the canvas, tools, and toolbar.
- select_tool: Allows users to select different drawing tools (pencil, rectangle, eraser).
- choose_color: Opens a color chooser to select drawing colors.
- start_draw: Initializes the starting point for drawing when the mouse button is pressed.
- draw: Handles the drawing logic based on the selected tool and mouse movement.
- save_drawing: Saves the current drawing to a file.
Solution 2: Basic Drawing App Using PyQt5
'PyQt5' is a set of Python bindings for Qt libraries that provides tools to create a GUI application.
Code:
# Solution 2: Basic Drawing App Using PyQt5
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QColorDialog, QFileDialog, QHBoxLayout, QVBoxLayout, QWidget
from PyQt5.QtGui import QPainter, QPen, QImage
from PyQt5.QtCore import Qt, QPoint
class DrawingApp(QMainWindow):
"""Class to create a simple drawing application with PyQt5."""
def __init__(self):
"""Initialize the DrawingApp with a PyQt5 main window."""
super().__init__()
self.setWindowTitle("Basic Drawing App")
self.setGeometry(100, 100, 600, 400)
# Initialize drawing settings
self.image = QImage(self.size(), QImage.Format_RGB32)
self.image.fill(Qt.white)
self.drawing = False
self.brush_color = Qt.black
self.brush_size = 2
self.last_point = QPoint()
# Set up the main layout
main_widget = QWidget()
main_layout = QVBoxLayout()
main_widget.setLayout(main_layout)
self.setCentralWidget(main_widget)
# Canvas area: the space above buttons
self.canvas = QWidget(self)
main_layout.addWidget(self.canvas) # Add canvas to the main layout
# Add horizontal layout for buttons at the bottom
button_layout = QHBoxLayout()
main_layout.addLayout(button_layout)
# Add buttons for tools
pencil_btn = QPushButton("Pencil", self)
pencil_btn.clicked.connect(self.select_pencil)
button_layout.addWidget(pencil_btn)
rect_btn = QPushButton("Rectangle", self)
rect_btn.clicked.connect(self.select_rectangle)
button_layout.addWidget(rect_btn)
color_btn = QPushButton("Color", self)
color_btn.clicked.connect(self.select_color)
button_layout.addWidget(color_btn)
save_btn = QPushButton("Save", self)
save_btn.clicked.connect(self.save_image)
button_layout.addWidget(save_btn)
def select_pencil(self):
"""Select the pencil tool for drawing."""
self.tool = 'pencil'
def select_rectangle(self):
"""Select the rectangle tool for drawing."""
self.tool = 'rectangle'
def select_color(self):
"""Open a color dialog to choose the drawing color."""
color = QColorDialog.getColor()
if color.isValid():
self.brush_color = color
def save_image(self):
"""Save the drawn image to a file."""
file_path, _ = QFileDialog.getSaveFileName(self, "Save Image", "", "PNG(*.png);;JPEG(*.jpg *.jpeg);;All Files(*.*) ")
if file_path:
self.image.save(file_path)
def mousePressEvent(self, event):
"""Handle mouse press events for drawing."""
if event.button() == Qt.LeftButton:
self.drawing = True
self.last_point = event.pos()
def mouseMoveEvent(self, event):
"""Handle mouse move events for drawing."""
if event.buttons() & Qt.LeftButton and self.drawing:
painter = QPainter(self.image)
painter.setPen(QPen(self.brush_color, self.brush_size, Qt.SolidLine))
painter.drawLine(self.last_point, event.pos())
self.last_point = event.pos()
self.update()
def mouseReleaseEvent(self, event):
"""Handle mouse release events to stop drawing."""
if event.button() == Qt.LeftButton:
self.drawing = False
def paintEvent(self, event):
"""Update the canvas to display the drawn elements."""
canvas_painter = QPainter(self)
canvas_painter.drawImage(self.rect(), self.image, self.image.rect())
# Run the PyQt5 application
app = QApplication([])
window = DrawingApp()
window.show()
app.exec_()
Output:
Explanation:
- Imports:
- PyQt5: Provides classes (QMainWindow, QPainter, QPen, QColorDialog, QFileDialog, etc.) for creating the GUI application.
- QApplication: Manages the GUI application's control flow.
- Class DrawingApp:
- __init__: Initializes the application window, sets up the drawing canvas, and adds tool buttons.
- select_pencil, select_rectangle, select_color: Handle user selections for tools and color.
- save_image: Saves the drawing to an image file.
- mousePressEvent, mouseMoveEvent, mouseReleaseEvent: Handle mouse events for drawing on the canvas.
- paintEvent: Updates the display to show drawn elements.
Summary of Differences:
- Tkinter Solution:
- Framework: Tkinter
- Features: Simple setup, minimal code, easy-to-understand GUI elements.
- Tools: Pencil, rectangle, color picker, eraser.
- Output: Saves drawing to a file.
- PyQt5 Solution:
- Framework: PyQt5
- Features: More advanced GUI features, customizable drawing tools.
- Tools: Pencil, rectangle, color picker.
- Output: Saves drawing to various image formats.
Both solutions provide a basic drawing application with essential functionalities, such as drawing shapes, selecting colors, and saving files.
It will be nice if you may share this link in any developer community or anywhere else, from where other developers may find this content. Thanks.
https://198.211.115.131/projects/python/python-basic-drawing-app-project.php
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics