Cách xây dựng ứng dụng Paint bằng Python

Lập trình ứng dụng vẽ tranh là bài luyện tập cơ bản, sẽ dạy bạn rất nhiều về lập trình GUI. Dưới đây là hướng dẫn cách tạo một ứng dụng vẽ tranh bằng Python.

App vẽ tranh trên Python

Một công cụ vẽ tranh đơn giản là ứng dụng phổ biến nhất mà bạn có thể tìm thấy trên hầu hết máy tính. Nó cho phép họa sĩ mắc lỗi mà không cần phải lo lắng, chọn màu bất kỳ bằng một click vào nút bấm, và thay đổi kích thước của cọ vẽ tức thì. Bạn có thể dùng nó để tạo logo thương hiệu, khái niệm hóa giao diện người dùng và chú thích sơ đồ.

Module Tkinter và Pillow

Để xây dựng ứng dụng vẽ tranh, bạn cần mô đun Tkinter và Pillow. Tkinter là một trong số những framework Python hàng đầu mà bạn có thể dùng để tùy biến GUI. Nó là mô đun GUI Python tiêu chuẩn để tạo các ứng dụng desktop. Tkinter mang tới một loạt widget khác nhau như label, entry, canvas và button.

Pillow, một nhánh của thư viện ảnh Python (PIL), là một mô đun xử lý ảnh cho Python. Với Pillow, bạn có thể mở, chỉnh lại kích thước, lật và cắt ảnh. Bạn có thể chuyển đổi cả định dạng file, xây dựng ứng dụng tìm công thức và tìm nạp ảnh ngẫu nhiên.

Để cài đặt những mô đun này, chạy:

pip install tk pillow

Xác định cấu trúc của ứng dụng vẽ tranh

Bắt đầu bằng cách nhập các mô đun được yêu cầu. Xác định một class, DrawApp. Đặt tiêu đề, màu con trỏ và màu cục tẩy. Làm ứng dụng mở ở toàn màn hình. Gọi phương thức setup_widgets.

import tkinter as tk
from tkinter.ttk import Scale
from tkinter import colorchooser, filedialog, messagebox
import PIL.ImageGrab as ImageGrab

class DrawApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Kids' Paint App")
        self.root.attributes("-fullscreen", True)
        self.pointer = "black"
        self.erase = "white"
        self.setup_widgets()

Xác định một phương thức tên setup_widgets. Xác định một nhãn hiện heading. Đặt thành phần cha, nội dung bạn muốn hiện, kiểu font, màu background, màu văn bản. Xác định một khung cho bảng màu. Đặt phần tử cha, nội dung nó sẽ hiện, kiểu font và chiều rộng đường viền. Đặt hình dạng đường viền như ý muốn và màu nền là màu trắng.

    def setup_widgets(self):
        self.title_label = tk.Label(
            self.root,
            text="Kids' Paint App",
            font=("Comic Sans MS", 30),
            bg="lightblue",
            fg="purple",
        )
        self.title_label.pack(fill=tk.X, pady=10)
        self.color_frame = tk.LabelFrame(
            self.root,
            text="Colors",
            font=("Comic Sans MS", 15),
            bd=5,
            relief=tk.RIDGE,
            bg="white",
        )
        self.color_frame.place(x=10, y=80, width=90, height=180)

Xác định một nhóm màu cho bảng màu trong một danh sách. Lặp lại nó và tạo nút bấm cho từng thành phần. Đặt thành phần cha, màu nền, chiều rộng đường viền và hình dáng của nó. Ngoài ra, đặt chiều rộng và lệnh cho mỗi nút sẽ chạy khi được click. Sắp xếp tất cả thành phần với padding phù hợp và màu sắc theo bộ của cả hai phần.

        colors = [
            "blue",
            "red",
            "green",
            "orange",
            "violet",
            "black",
            "yellow",
            "purple",
            "pink",
            "gold",
            "brown",
            "indigo",
        ]
        i, j = 0, 0
        for color in colors:
            tk.Button(
                self.color_frame,
                bg=color,
                bd=2,
                relief=tk.RIDGE,
                width=3,
                command=lambda col=color: self.select_color(col),
            ).grid(row=i, column=j, padx=2, pady=2)
            i += 1
            if i == 4:
                i = 0
                j = 1

Tương tự, xác định một nút bấm cho cục tẩy, một để xóa màn hình và một để lưu ảnh.

        self.eraser_btn = tk.Button(
            self.root,
            text="Eraser",
            bd=4,
            bg="white",
            command=self.eraser,
            width=9,
            relief=tk.RIDGE,
            font=("Comic Sans MS", 12),
        )
        self.eraser_btn.place(x=10, y=310)
        self.clear_screen_btn = tk.Button(
            self.root,
            text="Clear Screen",
            bd=4,
            bg="white",
            command=self.clear_screen,
            width=12,
            relief=tk.RIDGE,
            font=("Comic Sans MS", 12),
        )
        self.clear_screen_btn.place(x=10, y=370)
        self.save_as_btn = tk.Button(
            self.root,
            text="Save Drawing",
            bd=4,
            bg="white",
            command=self.save_as,
            width=12,
            relief=tk.RIDGE,
            font=("Comic Sans MS", 12),
        )
        self.save_as_btn.place(x=10, y=430)
        self.bg_btn = tk.Button(
            self.root,
            text="Background",
            bd=4,
            bg="white",
            command=self.canvas_color,
            width=12,
            relief=tk.RIDGE,
            font=("Comic Sans MS", 12),
        )
        self.bg_btn.place(x=10, y=490)
        self.pointer_frame = tk.LabelFrame(
            self.root,
            text="Size",
            bd=5,
            bg="white",
            font=("Comic Sans MS", 15, "bold"),
            relief=tk.RIDGE,
        )

Xác định widget tỷ lệ để tăng hoặc giảm kích thước của con trỏ hay cục tẩy. Đặt thành phần cha, hướng, phạm vi và chiều dài theo pixel. Xác định một canvas và đặt phần tử cha, màu background và chiều rộng đường viền. Ngoài ra, hãy thiết lập một hình có hình dạng phù hợp với chiều rộng và cao của nó.

Xác định vị trí canvas với tọa độ thích hợp và đặt anchor sang phía trên cùng bên trái. Liên kết B1-Motion sang hàm vẽ. B1 chỉ giữ nút chuột trái và Motion chỉ chuyển động. Nhìn chung, bạn dùng nó để theo dõi chuyển động chuột, trong khi nhấn nút chuột trái.

        self.pointer_frame.place(x=10, y=580, height=150, width=70)
        self.pointer_size = Scale(
            self.pointer_frame, orient=tk.VERTICAL, from_=48, to=1, length=120
        )
        self.pointer_size.set(1)
        self.pointer_size.grid(row=0, column=1, padx=15)
        self.canvas = tk.Canvas(
            self.root, bg="white", bd=5, relief=tk.GROOVE, height=650, width=1300
        )
        self.canvas.place(x=160, y=120, anchor="nw")
        self.canvas.bind("<B1-Motion>", self.paint)

Xác định tính năng của ứng dụng vẽ

Xác định một phương thức, paint. Để vẽ tranh, ứng dụng này sẽ liên tục vẽ các hình bầu dục nhỏ. Trừ 2 từ tọa độ xy của sự kiện chuột này để xác định góc trên bên trái của hình bầu dục. Thêm 2 để xác định góc phải phía dưới của hình bầu dục. Tạo một hình oval bằng những tọa độ giới hạn này.

Đặt màu tô, màu đường viền và chiều rộng cho mỗi lựa chọn con trỏ.

    def paint(self, event):
        x1, y1 = (event.x - 2), (event.y - 2)
        x2, y2 = (event.x + 2), (event.y + 2)
        self.canvas.create_oval(
            x1,
            y1,
            x2,
            y2,
            fill=self.pointer,
            outline=self.pointer,
            width=self.pointer_size.get(),
        )

Xác định 3 hàm, select_color, eraser, và clear_screen. Phương thức select_color lấy một màu và đặt con trỏ tương ứng. Phương thức eraser đặt con trỏ sang hiệu ứng giống như cục tẩy và làm nó vẽ các đường kẻ trong suốt. Phương thức clear_screen xóa toàn bộ mục trên canvas.

    def select_color(self, col):
        self.pointer = col

    def eraser(self):
        self.pointer = self.erase

    def clear_screen(self):
        self.canvas.delete("all")

Xác định một phương thức, canvas_color. Mở bộ chọn màu với tất cả màu sắc khác nhau. Mở bộ chọn màu sắc chứa tất cả các màu khác nhau. Trả về một bộ chứa màu ở định dạng RGB và thập lục phân. Nếu người dùng chọn màu, dùng phương thức configure để đặt màu nền. Đặt màu cục tẩy giống màu nền.

    def canvas_color(self):
        color = colorchooser.askcolor()
        if color:
            self.canvas.configure(background=color[1])
            self.erase = color[1]

Xác định phương thức save_as. Mở hộp thoại file yêu cầu người dùng chọn tên và đường dẫn tệp. Nếu người dùng chọn một đường dẫn, dùng class ImageGrab của Pillow để chụp toàn bộ màn hình. Cắt ảnh theo tọa độ cụ thể để lấy vùng canvas. Thử nghiệm với các tọa độ để lấy phần mong muốn.

Lưu kết quả sang đường dẫn file mong muốn. Hiện một box thông báo cho người dùng chương trình đã lưu bản vẽ thành công dưới dạng ảnh. Trong trường hợp phát sinh lỗi, nó hiện lỗi tương ứng.

    def save_as(self):
        file_path = filedialog.asksaveasfilename(
            defaultextension=".jpg", filetypes=[("Image files", "*.jpg")]
        )
        if file_path:
            try:
                y = 148
                x = 200
                y1 = 978
                x1 = 1840
                ImageGrab.grab().crop((x, y, x1, y1)).save(file_path)
                messagebox.showinfo("Save Drawing", "Image file saved successfully!")
            except Exception as e:
                messagebox.showerror("Error", f"Failed to save the image file: {e}")

Tạo phiên bản của class Tk DrawApp. Hàm mainloop() báo cho Python chạy lặp sự kiện Tkinter và lắng nghe các sự kiện cho tới khi bạn đóng cửa sổ.

if __name__ == "__main__":
    root = tk.Tk()
    app = DrawApp(root)
    root.mainloop()

Kiểm tra các tính năng vẽ khác nhau bằng Python

Khi chạy chương trình vẽ, bạn sẽ thấy một ứng dụng cùng một bảng màu, 4 nút bấm, một thanh trượt và một canvas để vẽ trên:

App vẽ tranh của trẻ em

Click màu bất kỳ để chọn nó. Sau đó, bạn có thể vẽ trên canvas trong màu đó với nút bấm chuột trái:

Chạy thử app vẽ tranh cho trẻ em

Khi click nút Eraser và kéo thanh trượt theo chiều dọc lên trên, bạn sẽ chọn cục tẩy và tăng kích thước của nó. Kiểm tra cục tẩy bằng cách kéo nó lên bản vẽ để xóa các nét không cần thiết.

Xóa nét vẽ không cần thiết

Khi click nút Clear Screen, chương trình xóa bản vẽ trước đó. Click nút Background để mở bảng màu và dùng nó để thay đổi màu background.

App vẽ tranh

Khi click nút Save Drawing, một hộp thoại file sẽ mở ra. Chọn đường dẫn và đặt tên cho file. Chương trình này sẽ lưu nó.

Hoàn tất ứng dụng vẽ tranh bằng Python

Bạn có thể nâng cao tính năng của ứng dụng vẽ bằng cách thêm lựa chọn bổ sung hình dạng, chọn kiểu cọ vẽ, độ mờ, dán sticker…. Thêm lựa chọn hoàn tác, làm lại, chỉnh kích thước, lật ảnh… Điều này khiến quá trình vẽ trở nên mượt mà hơn.

Để tạo hình dạng, bạn có thể dùng những phương thức như create_rectangle, create_oval, create_line, create_polygon. Để thêm ảnh, dùng create_text và create_image.

Trên đây là cách tạo app vẽ tranh bằng Python. Hi vọng bài viết hữu ích với các bạn.

Thứ Bảy, 09/09/2023 11:25
3,52 👨 531
0 Bình luận
Sắp xếp theo
    ❖ Python