Chuyển tới nội dung chính

Bài 1: Giới Thiệu Tkinter & Cửa Sổ Đầu Tiên

Giai đoạn 1 – Nhập Môn · Mục tiêu: Hiểu Tkinter là gì, tạo cửa sổ đầu tiên và nắm kiến trúc cơ bản của một ứng dụng GUI.


1. Tkinter là gì?​

Tkinter (viết tắt của Tk Interface) là thư viện GUI (Graphical User Interface) chuẩn của Python — tích hợp sẵn, không cần cài thêm.

Tkinter so với các thư viện GUI khác​

Thư việnƯu điểmNhược điểmPhù hợp
TkinterTích hợp sẵn, nhẹ, dễ họcGiao diện mặc định đơn giảnHọc tập, app nhỏ
PyQt6Đẹp, nhiều widget, cross-platformPhức tạp, cần cài đặtApp chuyên nghiệp
wxPythonNative look, nhiều tính năngNặng, khóApp desktop lớn
KivyHỗ trợ mobile, touch screenKhác biệt, khó họcMobile, touch

:::info Tại sao chọn Tkinter? Tkinter là điểm khởi đầu hoàn hảo cho lập trình GUI: không cần cài đặt, tài liệu phong phú, và đủ mạnh để xây dựng các ứng dụng desktop thực tế. :::


2. Kiến trúc ứng dụng Tkinter​

Mỗi ứng dụng Tkinter có cấu trúc cơ bản:

Tk() ← Cửa sổ gốc (root window)
├── Frame ← Khung chứa (container)
│ ├── Label ← Nhãn văn bản
│ ├── Button ← Nút bấm
│ └── Entry ← Ô nhập liệu
└── mainloop() ← Vòng lặp sự kiện

Vòng đời ứng dụng​

Khởi tạo Tk() → Tạo widget → Đặt layout → mainloop() → Chờ sự kiện → Xử lý → Lặp lại

3. Cửa sổ đầu tiên​

3.1. Hello Tkinter!​

import tkinter as tk

# Tạo cửa sổ gốc
root = tk.Tk()

# Cấu hình cửa sổ
root.title("Chương trình đầu tiên ")
root.geometry("400x300") # rộng x cao (pixel)

# Thêm nhãn văn bản
label = tk.Label(root, text="Xin chào Tkinter! ", font=("Arial", 18))
label.pack(pady=50)

# Khởi động vòng lặp sự kiện
root.mainloop()

Kết quả: Một cửa sổ 400×300 pixel hiện ra với dòng chữ "Xin chào Tkinter! ".

:::tip Giải thích từng dòng

  • tk.Tk() — tạo cửa sổ chính (chỉ gọi 1 lần)
  • root.title() — đặt tên hiển thị trên thanh tiêu đề
  • root.geometry("WxH") — kích thước cửa sổ (width × height)
  • root.mainloop() — bắt buộc ở cuối, giữ cửa sổ mở và lắng nghe sự kiện :::

4. Cấu hình cửa sổ chi tiết​

4.1. Kích thước và vị trí​

import tkinter as tk

root = tk.Tk()
root.title("Cấu hình cửa sổ")

# Kích thước + vị trí: "WxH+X+Y"
# W=rộng, H=cao, X=cách trái màn hình, Y=cách đỉnh màn hình
root.geometry("500x400+100+50")

# Kích thước tối thiểu / tối đa
root.minsize(300, 200)
root.maxsize(800, 600)

# Cố định kích thước (không cho resize)
root.resizable(False, False) # (chiều ngang, chiều dọc)

root.mainloop()

4.2. Căn giữa màn hình​

import tkinter as tk

def center_window(window, width, height):
"""Căn giữa cửa sổ trên màn hình."""
screen_w = window.winfo_screenwidth()
screen_h = window.winfo_screenheight()
x = (screen_w - width) // 2
y = (screen_h - height) // 2
window.geometry(f"{width}x{height}+{x}+{y}")

root = tk.Tk()
root.title("Cửa sổ căn giữa")
center_window(root, 500, 400)
root.mainloop()

4.3. Màu nền và icon​

import tkinter as tk

root = tk.Tk()
root.title("Giao diện tùy chỉnh")
root.geometry("400x300")

# Đặt màu nền
root.configure(bg="#2C3E50") # Màu xanh đậm

# Đặt icon (cần file .ico)
# root.iconbitmap("icon.ico")

# Màu nền cửa sổ
label = tk.Label(
root,
text="Giao diện tối",
font=("Arial", 16, "bold"),
fg="white", # Màu chữ
bg="#2C3E50" # Màu nền (phải khớp với root)
)
label.pack(expand=True)

root.mainloop()

5. Widget đầu tiên: Label và Button​

5.1. Label​

import tkinter as tk

root = tk.Tk()
root.title("Label Demo")
root.geometry("400x250")

# Label đơn giản
label1 = tk.Label(root, text="Label cơ bản")
label1.pack(pady=5)

# Label tùy chỉnh font
label2 = tk.Label(
root,
text="Font đẹp hơn",
font=("Helvetica", 14, "bold italic"),
fg="#E74C3C"
)
label2.pack(pady=5)

# Label nhiều dòng
label3 = tk.Label(
root,
text="Dòng 1\nDòng 2\nDòng 3",
justify="left", # left / center / right
bg="#ECF0F1",
padx=10, pady=5
)
label3.pack(pady=5)

root.mainloop()

5.2. Button​

import tkinter as tk

def click_me():
print("Bạn đã nhấn nút!")

root = tk.Tk()
root.title("Button Demo")
root.geometry("300x200")

# Button cơ bản
btn1 = tk.Button(root, text="Nhấn tôi!", command=click_me)
btn1.pack(pady=10)

# Button tùy chỉnh
btn2 = tk.Button(
root,
text="Button đẹp",
font=("Arial", 12, "bold"),
fg="white",
bg="#3498DB",
activebackground="#2980B9",
activeforeground="white",
padx=20, pady=8,
relief="flat", # flat / raised / sunken / groove / ridge
cursor="hand2" # Con trỏ chuột khi hover
)
btn2.pack(pady=10)

root.mainloop()

6. Thuộc tính widget phổ biến​

Thuộc tínhGiá trịMô tả
text"chuỗi"Văn bản hiển thị
font("Arial", 12, "bold")Font, cỡ chữ, kiểu
fg"red" hoặc "#FF0000"Màu chữ
bg"blue" hoặc "#0000FF"Màu nền
widthsố nguyênChiều rộng (ký tự)
heightsố nguyênChiều cao (dòng)
padxsố nguyênPadding ngang (pixel)
padysố nguyênPadding dọc (pixel)
reliefflat/raised/sunkenKiểu viền
cursor"hand2"/"arrow"Con trỏ chuột
statenormal/disabledTrạng thái kích hoạt

7. Chương trình hoàn chỉnh: Bộ đếm​

import tkinter as tk

class CounterApp:
def __init__(self, root):
self.root = root
self.root.title("Bộ đếm Tkinter")
self.root.geometry("300x200")
self.root.resizable(False, False)

self.count = 0

# Nhãn hiển thị số đếm
self.label = tk.Label(
root,
text="0",
font=("Arial", 48, "bold"),
fg="#2C3E50"
)
self.label.pack(pady=20)

# Frame chứa nút
btn_frame = tk.Frame(root)
btn_frame.pack()

tk.Button(btn_frame, text="", font=("Arial", 14),
command=self.decrement, width=4).pack(side="left", padx=5)

tk.Button(btn_frame, text="", font=("Arial", 14),
command=self.reset, width=4).pack(side="left", padx=5)

tk.Button(btn_frame, text="", font=("Arial", 14),
command=self.increment, width=4).pack(side="left", padx=5)

def increment(self):
self.count += 1
self.update_label()

def decrement(self):
self.count -= 1
self.update_label()

def reset(self):
self.count = 0
self.update_label()

def update_label(self):
color = "#27AE60" if self.count > 0 else "#E74C3C" if self.count < 0 else "#2C3E50"
self.label.config(text=str(self.count), fg=color)

# Chạy ứng dụng
root = tk.Tk()
app = CounterApp(root)
root.mainloop()

Bài tập thực hành​

Trắc nghiệm​

  1. Hàm nào giữ cửa sổ Tkinter luôn mở?

    • A. root.open()
    • B. root.mainloop()
    • C. root.run()
    • D. root.start()
  2. Phương thức nào đặt kích thước cửa sổ 400×300?

    • A. root.size("400x300")
    • B. root.resize(400, 300)
    • C. root.geometry("400x300")
    • D. root.width(400); root.height(300)
  3. Thuộc tính nào đặt màu chữ cho widget?

    • A. color
    • B. fg
    • C. text_color
    • D. foreground_color

Thực hành​

  1. Tạo cửa sổ 500×400, đặt màu nền #1A1A2E (xanh tối).
  2. Thêm một Label hiển thị tên bạn, font Arial 20 màu trắng.
  3. Viết hàm center_window() và áp dụng để căn giữa cửa sổ.
  4. (Nâng cao) Tạo app "Đồng hồ số" hiển thị giờ hiện tại, cập nhật mỗi giây dùng root.after(1000, func).

Bài tiếp: Bài 2 – Widget Cơ Bản