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