Chalothorn Kosakul 30 มิถุนายน, 2568 60 views
โปรแกรมคอมพิวเตอร์ที่เราใช้งานกันอยู่ทุกวัน ไม่ว่าจะเป็นเว็บเบราว์เซอร์ โปรแกรมพิมพ์งาน หรือแอปพลิเคชันบนสมาร์ทโฟน ล้วนมีส่วนติดต่อผู้ใช้แบบกราฟิก หรือที่เรียกว่า GUI (Graphical User Interface) ทั้งสิ้น GUI ช่วยให้ผู้ใช้สามารถโต้ตอบกับโปรแกรมได้ง่ายขึ้น ผ่านองค์ประกอบต่างๆ เช่น ปุ่ม, ช่องกรอกข้อความ, รูปภาพ, และเมนูต่างๆ แทนที่จะพิมพ์คำสั่งผ่าน Command Line ตลอดเวลา ในบทความนี้ เราจะเน้นไปที่ Tkinter ซึ่งเป็นไลบรารีที่มาพร้อมกับ Python ทำให้เราสามารถสร้างแอปพลิเคชัน GUI ได้อย่างรวดเร็วและง่ายดาย
สารบัญ:
1. โครงสร้างพื้นฐานของโปรแกรม Tkinter
2. การจัดการ Layout (pack, grid, place)
3. Widget พื้นฐาน (Label, Entry, Button, Text)
4. แสดงข้อความ/กล่องข้อความแจ้งเตือน
5. Widgets และคุณสมบัติอื่นๆ ที่น่าสนใจ
ทุกโปรแกรม Tkinter จะมีโครงสร้างพื้นฐานดังนี้:
import tkinter as tk
เราใช้ as tk
เพื่อให้เรียกใช้งานได้ง่ายขึ้น เช่น tk.Tk()
แทนที่จะเป็น tkinter.Tk()
root = tk.Tk()
root.title("ทกสอบโปรแกรม")
root.geometry("400x300") # กว้าง 400 พิกเซล, สูง 300 พิกเซล
เราสามารถกำหนดคุณสมบัติพื้นฐาน เช่น ชื่อเรื่องของหน้าต่าง (title) และขนาดของหน้าต่าง (geometry)
root.mainloop()
บรรทัดนี้สำคัญมาก เพราะมันจะทำให้หน้าต่าง GUI ของเราแสดงขึ้นมาและรอการโต้ตอบจากผู้ใช้ (เช่น การคลิกเมาส์ การพิมพ์คีย์บอร์ด) หากไม่มี mainloop()
หน้าต่างจะเปิดแล้วปิดไปทันที
import tkinter as tk
# 1. สร้างหน้าต่างหลัก
root = tk.Tk()
root.title("ทดสอบโปรแกรม")
root.geometry("400x300")
# 2. สร้าง Label (ข้อความ)
label = tk.Label(root, text="สวัสดี, Tkinter!")
label.pack(pady=20) # จัดวาง Label กลางหน้าจอและมีระยะห่างจากขอบบน 20 พิกเซล
# 3. เริ่ม Loop การทำงาน
root.mainloop()
เมื่อรันโค้ดนี้ จะเห็นหน้าต่างเล็กๆ ที่มีข้อความ "สวัสดี, Tkinter!" ปรากฏขึ้นมา
Tkinter มี Geometry Manager 3 แบบหลักๆ สำหรับจัดวาง Widget คือ pack()
, grid()
, และ place()
เราต้องบอก Tkinter ว่าจะวาง Widget เหล่านี้ไว้ตรงไหนบนหน้าต่าง
pack()
: จัดเรียง Widget แบบเรียงต่อกันpack()
เป็นวิธีที่ง่ายที่สุดในการจัดเรียง Widget มันจะจัดเรียง Widget ในแนวตั้งหรือแนวนอนตามลำดับที่เพิ่มเข้ามา
side
: กำหนดทิศทางการจัดเรียง (เช่น tk.TOP
, tk.BOTTOM
, tk.LEFT
, tk.RIGHT
)
fill
: กำหนดให้ Widget ขยายเพื่อเติมเต็มพื้นที่ (เช่น tk.X
, tk.Y
, tk.BOTH
)
expand
: กำหนดให้ Widget ขยายเมื่อหน้าต่างถูกปรับขนาด
padx
, pady
: กำหนดระยะห่างภายนอก (padding) ในแนวแกน X และ Y
import tkinter as tk
root = tk.Tk()
root.title("การใช้ pack()")
root.geometry("300x200")
btn1 = tk.Button(root, text="ปุ่ม 1")
btn1.pack(side=tk.TOP, pady=5) # วางด้านบน มีระยะห่าง 5
btn2 = tk.Button(root, text="ปุ่ม 2")
btn2.pack(side=tk.BOTTOM, fill=tk.X, padx=10) # วางด้านล่าง ขยายตามแนวนอน มีระยะห่าง 10
btn3 = tk.Button(root, text="ปุ่ม 3")
btn3.pack(side=tk.LEFT, padx=5, pady=5) # วางด้านซ้าย มีระยะห่าง 5 ทั้งคู่
root.mainloop()
grid()
: จัดเรียง Widget แบบตารางgrid()
เป็นวิธีที่มีประสิทธิภาพมากสำหรับการจัดวาง Widget ในรูปแบบตาราง (แถวและคอลัมน์) คล้ายกับการสร้างตารางใน Excel
row
: กำหนดแถวที่ Widget จะถูกวาง
column
: กำหนดคอลัมน์ที่ Widget จะถูกวาง
rowspan
, columnspan
: กำหนดให้ Widget กินพื้นที่หลายแถวหรือหลายคอลัมน์
padx
, pady
: กำหนดระยะห่างภายนอก
import tkinter as tk
root = tk.Tk()
root.title("การใช้ grid()")
root.geometry("300x200")
tk.Label(root, text="ชื่อผู้ใช้:").grid(row=0, column=0, padx=10, pady=5)
entry_username = tk.Entry(root)
entry_username.grid(row=0, column=1, padx=10, pady=5)
tk.Label(root, text="รหัสผ่าน:").grid(row=1, column=0, padx=10, pady=5)
entry_password = tk.Entry(root, show="*") # ซ่อนข้อความรหัสผ่าน
entry_password.grid(row=1, column=1, padx=10, pady=5)
btn_login = tk.Button(root, text="เข้าสู่ระบบ")
btn_login.grid(row=2, column=0, columnspan=2, pady=10) # ปุ่ม Login กิน 2 คอลัมน์
root.mainloop()
place()
: กำหนดตำแหน่งplace()
ช่วยให้คุณสามารถกำหนดตำแหน่งของ Widget ด้วยพิกัด X และ Y ที่แน่นอนบนหน้าต่าง หรือกำหนดตำแหน่งและขนาดแบบสัมพันธ์กับขนาดของหน้าต่างแม่
x
, y
: พิกัด X, Y จากมุมซ้ายบนของหน้าต่าง (ค่าเป็นพิกเซล)
relx
, rely
: พิกัด X, Y สัมพันธ์กับขนาดหน้าต่าง (ค่า 0.0 ถึง 1.0)
width
, height
: ความกว้างและความสูงของ Widget (ค่าเป็นพิกเซล)
relwidth
, relheight
: ความกว้างและความสูงสัมพันธ์กับขนาดหน้าต่าง (ค่า 0.0 ถึง 1.0)
ข้อควรระวัง place()
อาจทำให้การปรับขนาดหน้าต่างยากขึ้น เพราะตำแหน่งและขนาดอาจไม่ปรับตามอัตโนมัติ
import tkinter as tk
root = tk.Tk()
root.title("การใช้ place()")
root.geometry("400x250")
label1 = tk.Label(root, text="อยู่ตรงนี้เลย!", bg="lightblue")
label1.place(x=50, y=50, width=100, height=30)
label2 = tk.Label(root, text="อยู่มุมขวาบน!", bg="lightgreen")
label2.place(relx=1.0, rely=0.0, anchor=tk.NE, width=120, height=40) # NE คือ North-East (มุมขวาบน)
root.mainloop()
ควรเลือกใช้ Geometry Manager เพียงวิธีเดียว ต่อหนึ่ง Frame หรือ Window เพื่อไม่ให้เกิดความสับสน
การรับข้อมูลจากผู้ใช้เป็นสิ่งสำคัญสำหรับแอปพลิเคชัน GUI Tkinter มี Widget Entry
สำหรับรับข้อความบรรทัดเดียว และ Text
สำหรับรับข้อความหลายบรรทัด
Entry
Widget (รับข้อความบรรทัดเดียว)ใช้สำหรับรับข้อมูล เช่น ชื่อ, รหัสผ่าน, ตัวเลข
การสร้าง: entry_widget = tk.Entry(parent_widget)
การดึงข้อมูล: ใช้เมธอด .get()
เพื่อดึงข้อความจาก Entry
import tkinter as tk
def submit_name():
name = entry_name.get() # ดึงข้อความจาก entry_name
if name:
result_label.config(text=f"สวัสดี, {name}!") # แสดงผลใน Label
else:
result_label.config(text="กรุณาป้อนชื่อของคุณ!")
root = tk.Tk()
root.title("รับข้อมูลจาก Entry")
root.geometry("300x150")
tk.Label(root, text="ป้อนชื่อของคุณ:").pack(pady=5)
entry_name = tk.Entry(root, width=30)
entry_name.pack(pady=5)
button_submit = tk.Button(root, text="ตกลง", command=submit_name)
button_submit.pack(pady=5)
result_label = tk.Label(root, text="")
result_label.pack(pady=5)
root.mainloop()
Text
Widget (รับข้อความหลายบรรทัด)ใช้สำหรับรับข้อความยาวๆ เช่น คำอธิบาย หรือบันทึก
การสร้าง: text_widget = tk.Text(parent_widget, height=rows, width=columns)
การดึงข้อมูล: ใช้เมธอด .get("start_index", "end_index")
เช่น .get("1.0", tk.END)
เพื่อดึงข้อความทั้งหมด (1.0 คือแถวที่ 1, อักขระที่ 0; tk.END
คือจุดสิ้นสุด)
import tkinter as tk
def get_text_content():
content = text_area.get("1.0", tk.END).strip() # ดึงข้อความทั้งหมดและลบช่องว่างหัวท้าย
if content:
result_label.config(text=f"คุณเขียนว่า:\n{content}")
else:
result_label.config(text="ไม่มีข้อความถูกป้อน")
root = tk.Tk()
root.title("รับข้อมูลจาก Text Area")
root.geometry("400x300")
tk.Label(root, text="เขียนอะไรบางอย่าง:").pack(pady=5)
text_area = tk.Text(root, height=8, width=40)
text_area.pack(pady=5)
button_get_text = tk.Button(root, text="แสดงข้อความ", command=get_text_content)
button_get_text.pack(pady=5)
result_label = tk.Label(root, text="", justify=tk.LEFT) # จัดชิดซ้าย
result_label.pack(pady=5)
root.mainloop()
เราสามารถแสดงผลข้อมูลกลับไปยังผู้ใช้ได้หลายวิธี:
Label
Widget (แสดงข้อความ)เป็น Widget พื้นฐานที่สุดสำหรับแสดงข้อความ หรือรูปภาพ (ในกรณีของ Image Label)
การสร้าง: label = tk.Label(parent, text="ข้อความที่จะแสดง")
การเปลี่ยนข้อความ: ใช้เมธอด .config(text="ข้อความใหม่")
หรือตั้งค่า StringVar
ตัวอย่าง: (ดูได้จากตัวอย่างการรับข้อมูลจาก Entry ด้านบน)
Messagebox
(กล่องข้อความแจ้งเตือน)Tkinter มีโมดูล tkinter.messagebox
สำหรับแสดงกล่องข้อความแจ้งเตือน, ข้อผิดพลาด, หรือคำถาม
นำเข้า: from tkinter import messagebox
ฟังก์ชันที่ใช้บ่อย:
messagebox.showinfo("ชื่อหัวข้อ", "ข้อความแจ้งเตือน")
messagebox.showwarning("ชื่อหัวข้อ", "ข้อความเตือน")
messagebox.showerror("ชื่อหัวข้อ", "ข้อความผิดพลาด")
messagebox.askquestion("ชื่อหัวข้อ", "คำถาม")
(คืนค่า 'yes' หรือ 'no')
messagebox.askyesno("ชื่อหัวข้อ", "คำถาม")
(คืนค่า True หรือ False)
ตัวอย่าง:
import tkinter as tk
from tkinter import messagebox
def show_info():
messagebox.showinfo("ข้อมูล", "นี่คือกล่องข้อความข้อมูล")
def ask_question():
answer = messagebox.askyesno("คำถาม", "คุณแน่ใจหรือไม่?")
if answer:
tk.Label(root, text="คุณตอบว่า 'ใช่'").pack()
else:
tk.Label(root, text="คุณตอบว่า 'ไม่'").pack()
root = tk.Tk()
root.title("กล่องข้อความ")
root.geometry("250x150")
tk.Button(root, text="แสดงข้อมูล", command=show_info).pack(pady=5)
tk.Button(root, text="ถามคำถาม", command=ask_question).pack(pady=5)
root.mainloop()
นอกจาก Label, Entry, Button และ Text ยังมี Widget อื่นๆ ที่มีประโยชน์:
Button
: ปุ่มที่สามารถคลิกเพื่อเรียกใช้ฟังก์ชัน (ดูตัวอย่างด้านบน)
command
: กำหนดฟังก์ชันที่จะทำงานเมื่อปุ่มถูกคลิก
Checkbutton
: ช่องทำเครื่องหมาย (สามารถเลือกได้หลายอัน)
Radiobutton
: ปุ่มตัวเลือก (เลือกได้เพียงอันเดียวจากกลุ่ม)
Scale
: แถบเลื่อนสำหรับเลือกค่าตัวเลข
Scrollbar
: แถบเลื่อนสำหรับ Text
หรือ Listbox
ที่มีข้อมูลเยอะๆ
Canvas
: พื้นที่สำหรับวาดรูปภาพ, เส้น, หรือรูปร่างต่างๆ
Frame
: Widget ที่ใช้เป็นตัวจัดระเบียบ (container) สำหรับ Widget อื่นๆ ช่วยให้การจัดการ Layout ซับซ้อนทำได้ง่ายขึ้น
ตัวอย่างการใช้ Checkbutton
และ Radiobutton
:
import tkinter as tk
def show_selections():
selected_options = []
if var_pizza.get():
selected_options.append("พิซซ่า")
if var_pasta.get():
selected_options.append("พาสต้า")
if var_gender.get():
selected_options.append(f"เพศ: {var_gender.get()}")
if selected_options:
result_label.config(text="คุณเลือก:\n" + "\n".join(selected_options))
else:
result_label.config(text="ยังไม่ได้เลือกอะไรเลย")
root = tk.Tk()
root.title("ตัวอย่าง Widgets")
root.geometry("300x280")
# Checkbuttons
tk.Label(root, text="เลือกอาหารที่คุณชอบ:").pack(pady=5)
var_pizza = tk.IntVar() # ตัวแปรสำหรับเก็บค่า 0 หรือ 1
check_pizza = tk.Checkbutton(root, text="พิซซ่า", variable=var_pizza, onvalue=1, offvalue=0)
check_pizza.pack(anchor=tk.W) # จัดชิดซ้าย
var_pasta = tk.IntVar()
check_pasta = tk.Checkbutton(root, text="พาสต้า", variable=var_pasta, onvalue=1, offvalue=0)
check_pasta.pack(anchor=tk.W)
# Radiobuttons
tk.Label(root, text="เลือกเพศ:").pack(pady=10)
var_gender = tk.StringVar() # ตัวแปรสำหรับเก็บค่าข้อความ
radio_male = tk.Radiobutton(root, text="ชาย", variable=var_gender, value="ชาย")
radio_male.pack(anchor=tk.W)
radio_female = tk.Radiobutton(root, text="หญิง", variable=var_gender, value="หญิง")
radio_female.pack(anchor=tk.W)
button_show = tk.Button(root, text="แสดงผล", command=show_selections)
button_show.pack(pady=10)
result_label = tk.Label(root, text="", justify=tk.LEFT)
result_label.pack(pady=5)
root.mainloop()
Tkinter เป็นไลบรารีที่ใช้งานง่าย เหมาะสำหรับผู้เริ่มต้นเรียนรู้การสร้างโปรแกรม GUI ด้วย Python จุดเด่นคือไม่ต้องติดตั้งเพิ่มเติม และมีฟีเจอร์พื้นฐานเพียงพอสำหรับสร้างแอปพลิเคชันขนาดเล็กถึงกลางได้