Tkinter – Đồ họa

4.3/5 - (6 votes)

Trong phần này chúng ta sẽ học cách vẽ các đối tượng hình học trong Tkinter bằng cách sử dụng widget Canvas.

Vẽ đoạn thẳng

Để vẽ đoạn thẳng thì chúng ta dùng phương thức create_line() của lớp CanvasBạn cứ hiểu Canvas giống như một tờ giấy để chúng ta vẽ mọi thứ trên đó, nếu bạn đã từng lập trình HTML5 thì chắc không còn xa lạ gì với canvas.

from tkinter import Tk, Canvas, Frame, BOTH

class Example(Frame):
   def __init__(self, parent):
       Frame.__init__(self, parent)
       self.parent = parent
       self.initUI()
 
   def initUI(self):
       self.parent.title("Lines")
       self.pack(fill=BOTH, expand=1)
 
       canvas = Canvas(self)
       canvas.create_line(15, 25, 200, 25)
       canvas.create_line(300, 25, 300, 200, dash=(4, 2))
       canvas.create_line(55, 85, 155, 85, 105, 180, 55, 85)
 
       canvas.pack(fill=BOTH, expand=1)
 
root = Tk()
ex = Example(root)
root.geometry("400x250+300+300")
root.mainloop()

Trong ví dụ trên chúng ta vẽ một vài đoạn thẳng lên canvas.

canvas = Canvas(self)

Đầu tiên chúng ta tạo đối tượng Canvas với tham số self để canvas bao phủ toàn bộ cửa sổ.

canvas.create_line(15, 25, 200, 25)

Phương thức create_line() nhận vào tham số là tọa độ x, y của điểm bắt đầu và điểm kết thúc của một đoạn thẳng.

canvas.create_line(300, 35, 300, 200, dash=(4, 2))

Tham số dash tùy chỉnh kiểu vẽ là các đường nét đứt, ở ví dụ trên, dash=(4, 2) nghĩa là vẽ các nốt dài 4 pixel cách nhau 2 pixel.

canvas.create_line(55, 85, 155, 85, 105, 180, 55, 85)

Bạn cũng có thể đưa vào nhiều điểm, dòng code trên đưa vào 3 điểm để vẽ một hình tam giác.

Capture

Vẽ màu

Màu trong máy tính là màu RGB, là tổ hợp của 3 giá trị đỏ (Red), xanh lá (Green) và xanh lam (Blue).

from tkinter import Tk, Canvas, Frame, BOTH

class Example(Frame):
   def __init__(self, parent):
       Frame.__init__(self, parent)
       self.parent = parent
       self.initUI()
 
   def initUI(self):
       self.parent.title("Colors")
       self.pack(fill=BOTH, expand=1)
 
       canvas = Canvas(self)
       canvas.create_rectangle(30, 10, 120, 80, outline="#fb0", fill="#fb0")
       canvas.create_rectangle(150, 10, 240, 80, outline="#f50", fill="#f50")
       canvas.create_rectangle(270, 10, 370, 80, outline="#05f", fill="#05f")
       canvas.pack(fill=BOTH, expand=1)
 
root = Tk()
ex = Example(root)
root.geometry("400x100+300+300")
root.mainloop()

Trong ví dụ trên chúng ta vẽ 3 hình chữ nhật với 3 màu khác nhau.

canvas.create_rectangle(30, 10, 120, 80, 
    outline="#fb0", fill="#fb0")

Phương thức create_rectangle() tạo một hình chữ nhật trên canvas với 4 tham số đầu tiên là tọa độ x, y của điểm trái-trên và điểm phải-dưới. Tham số outline là giá trị màu đường viền, tham số fill là giá trị màu của hình chữ nhật, tất cả đều ở dạng hexa.

Capture

Vẽ một số đối tượng hình học khác

from tkinter import Tk, Canvas, Frame, BOTH

class Example(Frame):
   def __init__(self, parent):
       Frame.__init__(self, parent)
       self.parent = parent
       self.initUI()
 
   def initUI(self):
       self.parent.title("Shapes")
       self.pack(fill=BOTH, expand=1)
 
       canvas = Canvas(self)
 
       canvas.create_oval(10, 10, 80, 80, outline="gray", fill="gray", width=2)
       canvas.create_oval(110, 10, 210, 80, outline="gray", fill="gray", width=2)
       canvas.create_rectangle(230, 10, 290, 60, outline="gray", fill="gray", width=2)
       canvas.create_arc(30, 200, 90, 100, start=0, extent=210, outline="gray", fill="gray", width=2)
 
       points = [150, 100, 200, 120, 240, 180, 210, 200, 150, 150, 100, 200]
       canvas.create_polygon(points, outline="gray", fill="gray", width=2)
 
       canvas.pack(fill=BOTH, expand=1)
 
root = Tk()
ex = Example(root)
root.geometry("330x220+300+300")
root.mainloop()

Trong ví dụ trên chúng ta vẽ 5 hình là hình tròn, hình elip, hình chữ nhật, hình quạt và một đa giác.

canvas.create_oval(10, 10, 80, 80, outline="red", 
        fill="green", width=2)

Phương thức create_oval() dùng để vẽ hình tròn. Bốn tham số đầu tiên là tọa độ x, y của điểm trái-trên và phải-dưới của hình tròn (bởi vì hình tròn trong Tkinter được nằm trong một hình chữ nhật).

canvas.create_arc(30, 200, 90, 100, start=0, 
    extent=210, outline="#f11", fill="#1f1", width=2)

Phương thức create_arc() vẽ hình quạt, 4 tham số đầu tiên cũng là tọa độ hình chữ nhật chứa hình quạt này. Tham số start là hướng mà quạt hướng tới, tham số extend là độ lớn của quạt, cả 2 tham số này đều có đơn vị độ (từ 0 đến 360 độ).

points = [150, 100, 200, 120, 240, 180, 210, 
    200, 150, 150, 100, 200]
canvas.create_polygon(points, outline='red', 
    fill='green', width=2)

Phương thức create_polygon() vẽ một đa giác, tham số là tọa độ x, y của các điểm, bạn có thể đưa các điểm này vào bằng tay như các phương thức khác hoặc lưu các điểm trong một list rồi đưa list này vào.

Capture

Hiển thị ảnh từ file

from tkinter import Tk, Canvas, Frame, BOTH, NW
from PIL import Image, ImageTk

class Example(Frame):
   def __init__(self, parent):
       Frame.__init__(self, parent)
        self.parent = parent
        self.initUI()
      
   def initUI(self):
       self.parent.title("Image")
       self.pack(fill=BOTH, expand=1)
 
       self.img = Image.open("C:\\tatras.jpeg")
       self.tatras = ImageTk.PhotoImage(self.img)
 
       canvas = Canvas(self, width=self.img.size[0]+20, height=self.img.size[1]+20)
       canvas.create_image(10, 10, anchor=NW, image=self.tatras)
       canvas.pack(fill=BOTH, expand=1)

root = Tk()
ex = Example(root)
root.mainloop()     

Ví dụ trên vẽ hình từ file lên canvas.

self.img = Image.open("tatras.jpg")
self.tatras = ImageTk.PhotoImage(self.img)

Ở đây chúng ta dùng lớp ImageImageTk từ module PIL. Module này không có sẵn trong Python mà bạn phải tự cài thêm vào.

canvas = Canvas(self, width=self.img.size[0]+20, height=self.img.size[1]+20)

Chúng ta tạo đối tượng canvas với chiều dài và chiều rộng của file cộng thêm 20 pixel.

canvas.create_image(10, 10, anchor=NW, image=self.tatras)

Để hiện hình từ file lên canvas chúng ta dùng phương thức create_image(). Hai tham số đầu tiên là tọa độ góc trái-trên của hình. Tham số anchor=NW có tác dụng cắt hình từ vị trí NW = North West = tây-bắc) cho đến hết góc phải-dưới của ảnh, tức là lấy nguyên toàn bộ ảnh, mặc định nếu không đặt tham số này thì chương trình chỉ hiển thị phần giữa (CENTER) của ảnh. Bạn có thể thử các giá trị khác như N, E, SE (nhớ import các hằng số vô trước)… dưới đây là sơ đồ của các hướng.

tkanchor

Tham số image là đối tượng ảnh cần hiển thị.

Capture

Ghi chữ lên canvas

from tkinter import Tk, Canvas, Frame, BOTH, W

class Example(Frame):
   def __init__(self, parent):
       Frame.__init__(self, parent)  
       self.parent = parent 
       self.initUI()
 
 
   def initUI(self):
 
       self.parent.title("Lyrics") 
       self.pack(fill=BOTH, expand=1)

       canvas = Canvas(self)
       canvas.create_text(20, 30, anchor=W, font="VNI-Dom 18", 
                          text="Most relationships seem so transitory")
       canvas.create_text(20, 60, anchor=W, font="VNI-Dom 18", 
                          text="They're good but not the permanent one")
       canvas.create_text(20, 130, anchor=W, font="VNI-Dom 18", 
                          text="Who doesn't long for someone to hold")
       canvas.create_text(20, 160, anchor=W, font="VNI-Dom 18", 
                          text="Who knows how to love without being told") 
       canvas.create_text(20, 190, anchor=W, font="VNI-Dom 18", 
                          text="Somebody tell me why I'm on my own") 
       canvas.create_text(20, 220, anchor=W, font="VNI-Dom 18", 
                          text="If there's a soulmate for everyone") 
       canvas.pack(fill=BOTH, expand=1)

 
root = Tk()
ex = Example(root)
root.geometry("420x250+300+300")
root.mainloop() 

Đoạn code trên thực hiện “vẽ” lời bài hát lên canvas.

canvas.create_text(20, 30, anchor=W, font="VNI-Dom 18",
                   text="Most relationships seem so transitory")

Chúng ta dùng phương thức  create_text() để hiển thị chữ lên canvas. Hai tham số đầu là tọa độ x, y của góc trái trên. Tham số font="VNI-Dom 18" tức là dùng font VNI-Dom với độ lớn là 18px. Tham số text là nội dung đoạn text được in lên canvas.

Capture
5 3 votes
Article Rating
Subscribe
Thông báo cho tôi qua email khi
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

11 Comments
Inline Feedbacks
View all comments
Kaka
7 năm trước

Tôi muốn tạo một giao diện có thể thay đổi như la bàn thì dùng hàm gì để cập nhật hướng quay mới nhất ạ

van
van
4 năm trước

minh muốn hiển thị video thì như nao ad nhỉ

van
van
4 năm trước
Reply to  Phở Code

ad co the cho minh cap search dc ko a cu the thì mình có code object detection rồi nhưng muốn add nó vô giao diện ạ.

van
van
4 năm trước
Reply to  Phở Code

cảm ơn ad lần trước em làm được rồi ạ
vấn đề lần này của em là :
em muốn gắn một nút nhấn vô menu thì như nào ad ạ
và em muổn bỏ cái gạch ngang khi nhấp chuot vao menu ( cái gạch đứt đầu tiên khi nhấp vào menu ạ

van
van
4 năm trước
Reply to  Phở Code

ý e muốn là khi nào nhấn vô nó mới nhảy chương trình nhưng của e làm xong nó tự nhảy chương trình luôn ạ

van
van
4 năm trước
Reply to  Phở Code

em có làm rồi mà vẫn bị tự kích hoạt khi chưa click vào ạ

Swaim
Swaim
2 năm trước

vậy muốn dùng chuột vẽ trực tiếp lên thì sao ạ