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.
- Weekly Trends and Language Statistics
- Weekly Trends and Language Statistics