TKINTER TUTORIAL
Chương trình "Hello, World!" bằng Tkinter trong Python Tìm hiểu cửa sổ Tkinter trong Python Tìm hiểu về các Widget Tkinter trong Python 3 cách đặt Options cho Widget Tkinter trong Python Ràng buộc lệnh trong Tkinter Tìm hiểu Event Binding của Tkinter trong Python Giới thiệu widget Label trong Tkinter Cách sử dụng widget Entry trong Tkinter Trình quản lý hình học Pack trong Tkinter Trình quản lý hình học Grid trong Tkinter Trình quản lý hình học Place trong Tkinter Kích thước Widget trong Tkinter Tìm hiểu về widget Frame trong Tkinter Cách sử dụng widget Text của Tkinter Tìm hiểu về widget Scrollbar của Tkinter Cách sử dụng widget ScrolledText của Tkinter Cách sử dụng widget Separator của Tkinter Cách sử dụng Widget Checkbox Trong Tkinter Cách sử dụng widget radio button của Tkinter Cách tạo widget combobox trong Tkinter Cách sử dụng widget Listbox trong Tkinter Sử dụng widget PanedWindow trong Tkinter Cách tạo widget Spinbox trong Tkinter Hướng dẫn sử dụng Slider trong Tkinter Cách sử dụng widget Sizegrip trong Tkinter Cách sử dụng widget LabelFrame trong Tkinter Cách sử dụng widget Progressbar trong Tkinter Cách sử dụng widget Notebook trong Tkinter Cách sử dụng về widget Treeview trong Tkinter Hướng dẫn về Canvas trong Tkinter Cách thiết lập con trỏ widget trong Tkinter. Window hướng đối tượng trong Tkinter Các Frame hướng đối tượng trong Tkinter Cách sử dụng Object-Oriented Application trong Tkinter Phương thức tkraise() của Frame trong Tkinter Các kiểu (Styles) trong Tkinter Cách thay đổi theme trong Tkinter Các element của ttk trong Tkinter Tìm hiểu về đối tượng Tkinter StringVar trong Tkinter Cách sử dụng phương thức map() của ttk.Style Cách sử dụng phương thức after() của Tkinter Cách sử dụng threads trong Tkinter Cách hiển thị progress bar khi thread đang chạy trong Tkinter. Cách tạo nhiều cửa sổ trong một Tkinter Cách sử dụng widget PhotoImage của Tkinter Cấu trúc MVC trong Tkinter Cách sử dụng Validate trong Tkinter Cách hiển thị đồ thị từ thư viện Matplotlib trong Tkinter Ứng dụng System Tray với Tkinter
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.

Trình quản lý hình học Pack trong Tkinter

Trong việc phát triển ứng dụng giao diện người dùng (GUI) bằng Python, Tkinter là một trong những thư viện phổ biến nhất. Để tổ chức và sắp xếp các thành phần giao diện (widget) trên màn hình, Tkinter cung cấp nhiều trình quản lý hình học, trong đó Pack là một công cụ quan trọng và dễ sử dụng. Trong bài viết này, mình sẽ tìm hiểu cách sử dụng trình quản lý hình học Pack, tìm hiểu các tùy chọn của nó và cách áp dụng chúng để tạo ra các bố cục giao diện trực quan và hiệu quả. Bằng cách hiểu rõ về Pack, bạn sẽ có thể sắp xếp các widget một cách logic và tối ưu hóa trải nghiệm người dùng cho ứng dụng của mình.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Giới thiệu về trình quản lý hình học pack của Tkinter

Tkinter sử dụng các trình quản lý hình học để tổ chức các widget trên cửa sổ. Tkinter hỗ trợ ba trình quản lý hình học:

  • pack
  • grid
  • place

Trình quản lý hình học pack tổ chức các widget thành các khối trước khi đặt chúng lên container widget, có thể là cửa sổ chính hoặc một khung (frame).

Các tùy chọn của trình quản lý hình học pack

Trình quản lý hình học pack có nhiều tùy chọn để sắp xếp các widget, bao gồm:

Bài viết này được đăng tại [free tuts .net]

  • Side (Hướng)
  • Expand (Mở rộng)
  • Fill (Lấp đầy)
  • ipadx, ipady (Đệm bên trong)
  • padx, pady (Đệm bên ngoài)
  • Anchor (Điểm neo)

Trước khi đi sâu vào từng tùy chọn, bạn cần hiểu về tọa độ x và y của cửa sổ:

tkinter pack coordinates png

Góc trên bên trái của cửa sổ là gốc với tọa độ (0,0). Tọa độ x tăng từ trái sang phải và tọa độ y tăng từ trên xuống dưới.

Các tham số của pack trong Tkinter

Chúng ta sẽ tạo một chương trình đơn giản để minh họa cách hoạt động của trình quản lý hình học pack:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack()
label2.pack()
label3.pack()

root.mainloop()

Chương trình trên tạo ra một cửa sổ chính với ba nhãn có màu nền lần lượt là đỏ, xanh lá cây và xanh dương.

Để sử dụng trình quản lý hình học pack, bạn gọi phương thức pack() của widget. Mặc định, trình quản lý pack sắp xếp các widget theo chiều dọc từ trên xuống dưới.

tkinter pack side top png

Tùy chọn Side (Hướng)

Tham số side xác định hướng sắp xếp của các widget trong bố cục pack.

Tham số side có bốn tùy chọn:

  • 'top': sắp xếp các widget từ trên xuống dưới theo chiều dọc.
  • 'bottom': sắp xếp các widget từ dưới lên trên theo chiều dọc.
  • 'left': sắp xếp các widget từ trái sang phải theo chiều ngang.
  • 'right': sắp xếp các widget từ phải sang trái theo chiều ngang.

Mặc định, side'top', sắp xếp các widget theo chiều dọc từ trên xuống dưới.

Ngoài các hằng chuỗi, bạn có thể sử dụng các hằng số định sẵn được cung cấp bởi module Tkinter:

  • tk.TOP
  • tk.BOTTOM
  • tk.LEFT
  • tk.RIGHT

Ví dụ, chương trình sau đây đặt side'top', sắp xếp các nhãn theo chiều dọc từ trên xuống dưới:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack(side=tk.TOP)
label2.pack(side=tk.TOP)
label3.pack(side=tk.TOP)

root.mainloop()

Khi thay đổi side thành tk.BOTTOM, các nhãn sẽ được sắp xếp từ dưới lên trên theo chiều dọc:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack(side=tk.BOTTOM)
label2.pack(side=tk.BOTTOM)
label3.pack(side=tk.BOTTOM)

root.mainloop()

Kết quả:

tkinter pack side bottom png

tkinter pack side left png

tkinter pack side right png

Không gian của widget

Trong Tkinter, có hai loại không gian:

  1. Không gian mà một widget có thể chiếm: Là không gian mà container widget cung cấp cho widget.
  2. Không gian mà widget sẽ chiếm: Là không gian thực tế mà widget chiếm trong container.

Mặc định, một widget chỉ chiếm không gian cần thiết để hiển thị nội dung của nó. Tuy nhiên, một widget có thể chiếm nhiều không gian hơn nếu được chỉ định.

Ví dụ, một widget Label sẽ có kích thước tương ứng với văn bản. Màu nền cho thấy mỗi nhãn có chiều rộng khác nhau vì độ dài của văn bản khác nhau.

Tùy chọn Expand (Mở rộng)

Tham số expand xác định liệu widget có nên mở rộng để chiếm không gian trống được phân bổ cho container hay không.

Nếu expand được đặt là True, widget sẽ mở rộng, và nếu được đặt là False, nó sẽ không mở rộng. Mặc định, expandFalse.

Tham số expand phụ thuộc rất nhiều vào tham số side.

Bảng sau minh họa sự phụ thuộc giữa tham số sideexpand khi xét đến không gian của widget:

Side (Hướng) Expand (Mở rộng)
Top (hoặc Bottom) Widget có thể rộng bằng container, expand sẽ xác định chiều cao của widget.
Left (hoặc Right) Widget có thể cao bằng container, expand sẽ xác định chiều rộng của widget.

Chương trình sau đây sắp xếp các widget Label theo chiều dọc từ trên xuống dưới và đặt tham số expand của widget Label đầu tiên là True và của hai widget Label còn lại là False:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack(side=tk.TOP, expand=True)
label2.pack(side=tk.TOP, expand=False)
label3.pack(side=tk.TOP, expand=False)

root.mainloop()

Vì tham số expand của Label đầu tiên được đặt là True, nó chiếm toàn bộ không gian dọc và đẩy hai widget Label còn lại xuống dưới.

tkinter pack side top expand true png

Chương trình sau đây sắp xếp các widget Label theo chiều ngang từ trái sang phải và đặt tham số expand của widget Label đầu tiên là True và của hai widget Label còn lại là False:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack(side=tk.LEFT, expand=True)
label2.pack(side=tk.LEFT, expand=False)
label3.pack(side=tk.LEFT, expand=False)

root.mainloop()

Vì tham số expand của Label đầu tiên được đặt là True, nó chiếm toàn bộ không gian ngang và đẩy hai widget Label còn lại về bên phải.

tkinter pack side left expand true png

Nếu bạn đặt tham số expand của cả ba widget Label là True, chúng sẽ chiếm đều không gian ngang:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack(side=tk.LEFT, expand=True)
label2.pack(side=tk.LEFT, expand=True)
label3.pack(side=tk.LEFT, expand=True)

root.mainloop()

Tùy chọn Fill (Lấp đầy)

Tham số fill xác định liệu một widget có chiếm hết không gian sẵn có hay không. Nó chấp nhận các giá trị sau: 'x', 'y', 'both', và 'none'. Mặc định, fill'none'.

fill Tác dụng
x Mở rộng widget theo chiều ngang của container.
y Mở rộng widget theo chiều dọc của container.
both Mở rộng widget theo cả chiều ngang và chiều dọc của container.
none Không mở rộng widget. Đây là giá trị mặc định nếu fill không được chỉ định.

Bảng sau đây minh họa sự phụ thuộc giữa tham số sidefill khi xét đến không gian của widget:

Side (Hướng) Fill (Lấp đầy)
Top (hoặc Bottom) Widget có thể rộng bằng container, fill sẽ xác định chiều rộng của widget.
Left (hoặc Right) Widget có thể cao bằng container, fill sẽ xác định chiều cao của widget.

Chương trình sau đây sắp xếp các widget Label theo chiều dọc từ trên xuống dưới và đặt tham số fill của tất cả các widget Label là 'x':

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack(side=tk.TOP, fill=tk.X)
label2.pack(side=tk.TOP, fill=tk.X)
label3.pack(side=tk.TOP, fill=tk.X)

root.mainloop()

Các widget Label chiếm toàn bộ chiều ngang của container, nhưng không chiếm chiều dọc.

Chương trình sau đây sắp xếp các widget Label theo chiều ngang từ trái sang phải và đặt tham số fill của tất cả các widget Label là 'y':

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack(side=tk.LEFT, fill=tk.Y)
label2.pack(side=tk.LEFT, fill=tk.Y)
label3.pack(side=tk.LEFT, fill=tk.Y)

root.mainloop()

Các widget Label chiếm toàn bộ chiều dọc của container, nhưng không chiếm chiều ngang.

Chương trình sau đây sắp xếp các widget Label theo chiều dọc từ trên xuống dưới và đặt tham số fill của tất cả các widget Label là 'both':

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack(side=tk.TOP, fill=tk.BOTH)
label2.pack(side=tk.TOP, fill=tk.BOTH)
label3.pack(side=tk.TOP, fill=tk.BOTH)

root.mainloop()

Các widget Label chiếm toàn bộ không gian của container.

tkinter pack ipadx ipady png

Đệm bên trong (ipadx, ipady)

Tham số ipadx xác định khoảng cách theo chiều ngang giữa nội dung và biên của widget. Tương tự, ipady xác định khoảng cách theo chiều dọc giữa nội dung và biên của widget.

Nếu bạn không chỉ định các tham số ipadxipady, các widget sẽ không có đệm bên trong.

tkinter pack pady png

Chương trình sau đây đặt ipadx là 10 và ipady là 5 cho tất cả các widget Label:

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack(ipadx=10, ipady=5)
label2.pack(ipadx=10, ipady=5)
label3.pack(ipadx=10, ipady=5)

root.mainloop()

Kết quả:

tkinter pack padx png

Tùy chọn Anchor (Điểm neo)

Tham số anchor xác định vị trí của widget trên container widget. Nó chấp nhận các giá trị sau:

tkinter pack anchor illustration png

  • 'n': trên cùng
  • 'e': bên phải
  • 's': dưới cùng
  • 'w': bên trái
  • 'center': trung tâm
  • 'ne': góc trên bên phải
  • 'nw': góc trên bên trái
  • 'se': góc dưới bên phải
  • 'sw': góc dưới bên trái

tkinter pack anchor demo png

Chương trình sau đây đặt anchor của các widget Label đầu tiên và thứ hai lần lượt là 'n''se':

import tkinter as tk

root = tk.Tk()
root.title('Tkinter Pack Layout')
root.geometry('600x400')

label1 = tk.Label(master=root, text='Tkinter', bg='red', fg='white')
label2 = tk.Label(master=root, text='Pack Layout', bg='green', fg='white')
label3 = tk.Label(master=root, text='Demo', bg='blue', fg='white')

label1.pack(anchor='n')
label2.pack(anchor='se')
label3.pack(anchor='center')

root.mainloop()

Kết quả:

tkinter pack login form png

Kết bài

Mình đã cùng tìm các tính năng và tùy chọn của trình quản lý hình học Pack trong Tkinter. Từ việc sắp xếp các widget theo hướng dọc hoặc ngang, đến việc điều chỉnh kích thước và khoảng cách của chúng bằng các tham số như expand, fill, padx, pady, ipadx, và ipady, Pack cung cấp một cách tiếp cận linh hoạt và hiệu quả để thiết kế giao diện người dùng. Hiểu và áp dụng đúng các tùy chọn của Pack sẽ giúp bạn tạo ra các giao diện đẹp mắt và dễ sử dụng cho ứng dụng của mình. Hãy thử nghiệm và điều chỉnh các tham số này để tìm ra giải pháp tốt nhất cho nhu cầu thiết kế của bạn, và nhớ rằng việc làm quen với các trình quản lý hình học khác như Grid và Place cũng sẽ mở rộng khả năng của bạn trong việc xây dựng giao diện Tkinter. Chúc bạn thành công trong việc phát triển các ứng dụng Tkinter của mình!

Cùng chuyên mục:

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn toàn diện về module datetime trong Python

Hướng dẫn toàn diện về module datetime trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Từ khóa yield trong Python

Từ khóa yield trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Định dạng chuỗi Strings trong Python

Định dạng chuỗi Strings trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Làm việc với các biến môi trường trong Python

Làm việc với các biến môi trường trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa iterator và iterable trong Python

Sự khác biệt giữa iterator và iterable trong Python

Cách làm việc với file tarball/tar trong Python

Cách làm việc với file tarball/tar trong Python

Chuyển đổi kiểu dữ liệu trong Python

Chuyển đổi kiểu dữ liệu trong Python

Sự khác biệt giữa toán tử == và is trong Python

Sự khác biệt giữa toán tử == và is trong Python

Làm việc với file ZIP trong Python

Làm việc với file ZIP trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Sự khác biệt giữa byte objects và string trong Python

Sự khác biệt giữa byte objects và string trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format  trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Top