Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
Các Frame hướng đối tượng trong Tkinter
Trong giao diện người dùng với Tkinter, việc tổ chức mã nguồn theo hướng đối tượng là một cách tiếp cận hiệu quả để xây dựng các ứng dụng linh hoạt và dễ bảo trì. Thay vì tạo và quản lý các widget trong hàm chính, bạn có thể tận dụng sức mạnh của các lớp và đối tượng để xây dựng các khung (Frame) có cấu trúc rõ ràng. Bài viết này sẽ hướng dẫn bạn cách kế thừa từ lớp ttk.Frame và sử dụng nó trong cửa sổ chính của ứng dụng Tkinter, giúp bạn tổ chức mã nguồn một cách gọn gàng và dễ dàng mở rộng.

Giới thiệu các Frame hướng đối tượng trong Tkinter
Trong bài hướng dẫn trước, bạn đã học cách kế thừa từ lớp Tkinter.Tk. Tuy nhiên, một ứng dụng Tkinter chỉ nên có một phiên bản Tk duy nhất. Do đó, việc kế thừa từ lớp ttk.Frame và sử dụng lớp con đó trong cửa sổ chính là điều phổ biến.
Để kế thừa từ lớp ttk.Frame, bạn sử dụng cú pháp sau:
class MainFrame(ttk.Frame):
pass
Vì một Frame cần một container, bạn cần thêm một tham số vào phương thức __init__() và gọi phương thức __init__() của lớp ttk.Frame như sau:
Bài viết này được đăng tại [free tuts .net]
class MainFrame(ttk.Frame):
def __init__(self, container):
super().__init__(container)
Dưới đây là ví dụ về lớp MainFrame hoàn chỉnh có chứa một nhãn (label) và một nút bấm (button). Khi bạn nhấn nút, nó sẽ hiển thị một hộp thoại thông báo:
class MainFrame(ttk.Frame):
def __init__(self, container):
super().__init__(container)
options = {'padx': 5, 'pady': 5}
# Nhãn
self.label = ttk.Label(self, text='Hello, Tkinter!')
self.label.pack(**options)
# Nút bấm
self.button = ttk.Button(self, text='Click Me')
self.button['command'] = self.button_clicked
self.button.pack(**options)
# Hiển thị frame trên container
self.pack(**options)
def button_clicked(self):
showinfo(title='Information',
message='Hello, Tkinter!')
Tiếp theo, chúng ta định nghĩa lớp App kế thừa từ lớp Tk:
class App(tk.Tk):
def __init__(self):
super().__init__()
# Cấu hình cửa sổ chính
self.title('My Awesome App')
self.geometry('300x100')
Cuối cùng, bạn có thể khởi chạy ứng dụng thông qua khối lệnh if __name__ == "__main__":
if __name__ == "__main__":
app = App()
frame = MainFrame(app)
app.mainloop()
Trong đoạn mã trên:
- Đầu tiên, tạo một phiên bản mới của lớp
App. - Sau đó, tạo một phiên bản mới của lớp
MainFramevà đặt container của nó là phiên bản của lớpApp. - Cuối cùng, khởi động ứng dụng bằng cách gọi
app(). Điều này sẽ thực thi phương thức__call__()và kích hoạt vòng lặp chính (mainloop) của cửa sổ chính.
Hoàn chỉnh mã nguồn:
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo
class MainFrame(ttk.Frame):
def __init__(self, container):
super().__init__(container)
options = {'padx': 5, 'pady': 5}
# Nhãn
self.label = ttk.Label(self, text='Hello, Tkinter!')
self.label.pack(**options)
# Nút bấm
self.button = ttk.Button(self, text='Click Me')
self.button['command'] = self.button_clicked
self.button.pack(**options)
# Hiển thị frame trên container
self.pack(**options)
def button_clicked(self):
showinfo(title='Information',
message='Hello, Tkinter!')
class App(tk.Tk):
def __init__(self):
super().__init__()
# Cấu hình cửa sổ chính
self.title('My Awesome App')
self.geometry('300x100')
if __name__ == "__main__":
app = App()
frame = MainFrame(app)
app.mainloop()
Kết quả:

Ví dụ khung hướng đối tượng khác trong Tkinter
Ví dụ sau sử dụng các lớp để chuyển đổi cửa sổ Replace từ bài hướng dẫn về Frame:
import tkinter as tk
from tkinter import ttk
class InputFrame(ttk.Frame):
def __init__(self, container):
super().__init__(container)
# Cài đặt trình quản lý bố cục lưới
self.columnconfigure(0, weight=1)
self.columnconfigure(0, weight=3)
self.__create_widgets()
def __create_widgets(self):
# Nhãn "Find what"
ttk.Label(self, text='Find what:').grid(column=0, row=0, sticky=tk.W)
keyword = ttk.Entry(self, width=30)
keyword.focus()
keyword.grid(column=1, row=0, sticky=tk.W)
# Nhãn "Replace with"
ttk.Label(self, text='Replace with:').grid(column=0, row=1, sticky=tk.W)
replacement = ttk.Entry(self, width=30)
replacement.grid(column=1, row=1, sticky=tk.W)
# Ô chọn "Match Case"
match_case = tk.StringVar()
match_case_check = ttk.Checkbutton(
self,
text='Match case',
variable=match_case,
command=lambda: print(match_case.get()))
match_case_check.grid(column=0, row=2, sticky=tk.W)
# Ô chọn "Wrap Around"
wrap_around = tk.StringVar()
wrap_around_check = ttk.Checkbutton(
self,
variable=wrap_around,
text='Wrap around',
command=lambda: print(wrap_around.get()))
wrap_around_check.grid(column=0, row=3, sticky=tk.W)
for widget in self.winfo_children():
widget.grid(padx=0, pady=5)
class ButtonFrame(ttk.Frame):
def __init__(self, container):
super().__init__(container)
# Cài đặt trình quản lý bố cục lưới
self.columnconfigure(0, weight=1)
self.__create_widgets()
def __create_widgets(self):
ttk.Button(self, text='Find Next').grid(column=0, row=0)
ttk.Button(self, text='Replace').grid(column=0, row=1)
ttk.Button(self, text='Replace All').grid(column=0, row=2)
ttk.Button(self, text='Cancel').grid(column=0, row=3)
for widget in self.winfo_children():
widget.grid(padx=0, pady=3)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title('Replace')
self.geometry('400x150')
self.resizable(0, 0)
# Chỉ dành cho Windows (loại bỏ nút thu nhỏ/phóng to)
self.attributes('-toolwindow', True)
# Bố trí trên cửa sổ chính
self.columnconfigure(0, weight=4)
self.columnconfigure(1, weight=1)
self.__create_widgets()
def __create_widgets(self):
# Tạo frame nhập liệu
input_frame = InputFrame(self)
input_frame.grid(column=0, row=0)
# Tạo frame các nút bấm
button_frame = ButtonFrame(self)
button_frame.grid(column=1, row=0)
if __name__ == "__main__":
app = App()
app.mainloop()
Kết quả:

Kết bài
Qua bài viết này, bạn đã học cách kế thừa từ lớp ttk.Frame và khởi tạo các widget trực tiếp trên frame, giúp mã nguồn trở nên gọn gàng và dễ quản lý hơn. Việc sử dụng lớp con của ttk.Frame trong cửa sổ chính của ứng dụng Tkinter không chỉ giúp bạn xây dựng các giao diện phức tạp một cách hiệu quả mà còn làm tăng khả năng tái sử dụng và mở rộng của mã nguồn. Đây là một kỹ thuật quan trọng trong lập trình hướng đối tượng, đặc biệt hữu ích khi phát triển các ứng dụng GUI với Tkinter.

Các kiểu dữ liệu trong C ( int - float - double - char ...)
Thuật toán tìm ước chung lớn nhất trong C/C++
Cấu trúc lệnh switch case trong C++ (có bài tập thực hành)
ComboBox - ListBox trong lập trình C# winforms
Random trong Python: Tạo số random ngẫu nhiên
Lệnh cin và cout trong C++
Cách khai báo biến trong PHP, các loại biến thường gặp
Download và cài đặt Vertrigo Server
Thẻ li trong HTML
Thẻ article trong HTML5
Cấu trúc HTML5: Cách tạo template HTML5 đầu tiên
Cách dùng thẻ img trong HTML và các thuộc tính của img
Thẻ a trong HTML và các thuộc tính của thẻ a thường dùng