การสร้าง GUI ด้วย Python และ Tkinter

ห้องเรียนออนไลน์python

การสร้าง GUI ด้วย Python และ Tkinter

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 และคุณสมบัติอื่นๆ ที่น่าสนใจ


1. โครงสร้างพื้นฐานของโปรแกรม Tkinter

ทุกโปรแกรม Tkinter จะมีโครงสร้างพื้นฐานดังนี้:

1) นำเข้าโมดูล Tkinter:

import tkinter as tk

เราใช้ as tk เพื่อให้เรียกใช้งานได้ง่ายขึ้น เช่น tk.Tk() แทนที่จะเป็น tkinter.Tk()


2) สร้างหน้าต่างหลัก (Root Window):

root = tk.Tk()

3) กำหนดคุณสมบัติของหน้าต่าง:

root.title("ทกสอบโปรแกรม")
root.geometry("400x300") # กว้าง 400 พิกเซล, สูง 300 พิกเซล

เราสามารถกำหนดคุณสมบัติพื้นฐาน เช่น ชื่อเรื่องของหน้าต่าง (title) และขนาดของหน้าต่าง (geometry)


4) เริ่ม Loop การทำงานของ GUI (Main Event Loop):

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!" ปรากฏขึ้นมา


2. จัดการการจัดวาง Layout:

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 เพื่อไม่ให้เกิดความสับสน


3. Widget พื้นฐาน (Label, Entry, Button, Text):

การรับข้อมูลจากผู้ใช้เป็นสิ่งสำคัญสำหรับแอปพลิเคชัน 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()


4. แสดงข้อความ/กล่องข้อความแจ้งเตือน

เราสามารถแสดงผลข้อมูลกลับไปยังผู้ใช้ได้หลายวิธี:

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()


5. Widgets และคุณสมบัติอื่นๆ ที่น่าสนใจ

นอกจาก 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 จุดเด่นคือไม่ต้องติดตั้งเพิ่มเติม และมีฟีเจอร์พื้นฐานเพียงพอสำหรับสร้างแอปพลิเคชันขนาดเล็กถึงกลางได้


แชร์ข่าวนี้