[ก๊อปวางแล้วใช้ได้เลย] มาสร้างแอป Notepad ง่ายๆ ด้วย Python กันเถอะ! (พร้อมฟังก์ชันบันทึกไฟล์)
"อยากลองเขียนโปรแกรมสร้างอะไรสักอย่างที่จับต้องได้จัง!"
สำหรับคุณที่กำลังคิดแบบนั้นอยู่ บทความนี้จะอธิบายวิธีสร้าง "แอป Notepad" ง่ายๆ ในแบบของคุณเอง ที่สามารถพิมพ์ข้อความและบันทึกเป็นไฟล์ได้ด้วยภาษา Python ในแบบที่เข้าใจง่ายที่สุดในโลกครับ
สวัสดีครับ! ผมเป็นนักพัฒนาเว็บที่เรียนรู้ด้วยตัวเองโดยใช้ AI ช่วย ซึ่งเมื่อไม่กี่เดือนก่อนยังไม่มีความรู้ด้านโปรแกรมมิ่งเลยแม้แต่น้อย ตอนแรกผมก็อยู่ในระดับที่ว่า "บันทึกไฟล์เหรอ? มันคือคาถาอะไรหรือเปล่า?" (555) เพราะอย่างนั้น ผมเลยตั้งใจจะใช้ศัพท์เทคนิคให้น้อยที่สุด แล้วมาแชร์จุดที่ผมเคยติดขัดสมัยเป็นมือใหม่เหมือนกันไปพร้อมๆ กับทุกคนครับ
เป้าหมายของบทความนี้มีเพียงหนึ่งเดียว นั่นคือ เพื่อให้คุณได้สัมผัสกับความรู้สึกประทับใจที่ว่า "โปรแกรมที่ฉันสร้างเองมันทำงานได้!" ครับ ด้วยเหตุนี้ เรื่องยากๆ เราจะเก็บไว้ทีหลัง! ก่อนอื่น มาลองสัมผัสกับโค้ดที่สมบูรณ์แบบที่แค่ก๊อปวางก็ทำงานได้กันเลย!
ขั้นตอนที่ 1: มาลองรันกันเลย! โค้ดที่สมบูรณ์อยู่ตรงนี้แล้ว
สิบปากว่าไม่เท่าตาเห็นครับ ก่อนอื่นให้คัดลอกโค้ดด้านล่างทั้งหมด ไปบันทึกเป็นไฟล์ชื่อ memo_app.py แล้วลองรันดูได้เลยครับ สำหรับใครที่ยังไม่มีสภาพแวดล้อมสำหรับรัน Python ก็เตรียมให้พร้อมก่อนนะครับ
ถ้าคุณคิดว่า "เอ๊ะ, นี่โค้ดสำเร็จรูปแล้วเหรอ?" "แล้วคำอธิบายล่ะ?" คุณคิดถูกแล้วครับ! การได้สัมผัสประสบการณ์ว่า "มันทำงานได้" ก่อน คือเคล็ดลับที่สนุกที่สุดในการเรียนเขียนโปรแกรมครับ
import tkinter as tk
import tkinter.filedialog as filedialog
def save_file():
"""ฟังก์ชันสำหรับบันทึกไฟล์"""
file_path = filedialog.asksaveasfilename(
defaultextension=".txt",
filetypes=[("ไฟล์ข้อความ", "*.txt"), ("ไฟล์ทั้งหมด", "*.*")]
)
if not file_path:
return
try:
with open(file_path, 'w', encoding='utf-8') as file:
text_content = text_area.get(1.0, tk.END)
file.write(text_content)
except Exception as e:
print(f"เกิดข้อผิดพลาด: {e}")
def open_file():
"""ฟังก์ชันสำหรับเปิดไฟล์"""
file_path = filedialog.askopenfilename(
filetypes=[("ไฟล์ข้อความ", "*.txt"), ("ไฟล์ทั้งหมด", "*.*")]
)
if not file_path:
return
try:
with open(file_path, 'r', encoding='utf-8') as file:
text_content = file.read()
text_area.delete(1.0, tk.END)
text_area.insert(tk.END, text_content)
except Exception as e:
print(f"เกิดข้อผิดพลาด: {e}")
# สร้างหน้าต่างหลัก
window = tk.Tk()
window.title("Notepad แบบง่าย")
window.geometry("600x400")
# สร้างพื้นที่สำหรับป้อนข้อความ
text_area = tk.Text(window, wrap=tk.WORD)
text_area.pack(expand=True, fill=tk.BOTH)
# สร้างแถบเมนู
menu_bar = tk.Menu(window)
window.config(menu=menu_bar)
# สร้างเมนู "ไฟล์"
file_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="ไฟล์", menu=file_menu)
file_menu.add_command(label="เปิด...", command=open_file)
file_menu.add_command(label="บันทึกเป็น...", command=save_file)
file_menu.add_separator()
file_menu.add_command(label="ออก", command=window.quit)
# แสดงหน้าต่าง
window.mainloop()
เป็นยังไงบ้างครับ? ถ้ามีหน้าต่างแบบนี้ปรากฏขึ้นมาก็ถือว่าสำเร็จอย่างงดงาม!
ลองพิมพ์ข้อความ หรือเลือก "บันทึกเป็น..." กับ "เปิด..." จากเมนูดูสิครับ ไม่รู้สึกประทับใจหน่อยเหรอที่มันทำงานเป็นโปรแกรม Notepad ได้จริงๆ?
ขั้นตอนที่ 2: สำรวจโค้ด! มาแอบดูการทำงานของมันกัน
หลังจากที่ได้สัมผัสประสบการณ์ "มันทำงานได้!" กันไปแล้ว ต่อไปเรามาสำรวจกันว่า "ทำไมมันถึงทำงานได้?" กันดีกว่าครับ เราจะมาแยกส่วนโค้ดเมื่อสักครู่ออกเป็นชิ้นๆ แล้วอธิบายหน้าที่ของแต่ละส่วนกัน
① เตรียมกล่องเครื่องมือวิเศษ (import)
โค้ดสองบรรทัดแรกเปรียบเสมือนคาถาสำหรับเรียก "เครื่องมืออำนวยความสะดวก" ที่เราจะใช้เข้ามาใน Python ครับ
import tkinter as tk
import tkinter.filedialog as filedialog
- `tkinter`: เป็นไลบรารีมาตรฐานของ Python สำหรับสร้าง GUI (Graphical User Interface) อย่างหน้าต่างหรือปุ่มต่างๆ ได้อย่างง่ายดาย พูดง่ายๆ ก็คือเป็นกล่องเครื่องมือสำหรับสร้างโครงสร้างและชิ้นส่วนของแอปครับ
- `tkinter.filedialog`: เป็นเครื่องมือพิเศษสำหรับแสดงกล่องโต้ตอบ (dialog box) ที่เราคุ้นเคยกันดีอย่าง "เปิดไฟล์" หรือ "บันทึกเป็น" ครับ
② สร้างฐานรากของแอป (การสร้างหน้าต่าง)
ต่อไป เราจะสร้างหน้าต่างหลักของแอปกันครับ ถ้าเปรียบกับการสร้างบ้าน ส่วนนี้ก็คือการวางฐานรากและขึ้นโครงสร้างนั่นเอง
# สร้างหน้าต่างหลัก
window = tk.Tk()
window.title("Notepad แบบง่าย")
window.geometry("600x400")
# ... (โค้ดส่วนอื่น) ...
# แสดงหน้าต่าง
window.mainloop()
- `window = tk.Tk()`: นี่คือคำสั่งสำหรับสร้างตัวหน้าต่างหลักครับ มีความหมายว่า "ช่วยสร้างหน้าต่างที่ชื่อว่า `window` จากพิมพ์เขียวที่ชื่อ `Tk()` ในกล่องเครื่องมือ `tk` ให้หน่อย"
- `window.title(...)`: ใช้สำหรับตั้งค่าข้อความที่จะแสดงบนแถบหัวเรื่อง (title bar) ของหน้าต่าง
- `window.geometry("600x400")`: ใช้สำหรับกำหนดขนาดเริ่มต้นของหน้าต่างเป็น "กว้าง 600 พิกเซล × สูง 400 พิกเซล"
- `window.mainloop()`: นี่คือส่วนที่สำคัญที่สุด! เป็นคำสั่งสำหรับแสดงหน้าต่างที่สร้างขึ้นและรอการทำงานจากผู้ใช้ไปเรื่อยๆ จนกว่าจะถูกปิด ถ้าไม่มีบรรทัดนี้ โปรแกรมจะทำงานเสร็จและปิดตัวลงในพริบตาจนเรามองไม่เห็นหน้าต่างเลยครับ
③ เตรียมพื้นที่สำหรับเขียน (พื้นที่ข้อความ)
ไหนๆ ก็เป็น Notepad แล้ว ก็ต้องมีพื้นที่สำหรับพิมพ์ข้อความใช่ไหมครับ ส่วนนี้แหละครับที่ทำหน้าที่นั้น
# สร้างพื้นที่สำหรับป้อนข้อความ
text_area = tk.Text(window, wrap=tk.WORD)
text_area.pack(expand=True, fill=tk.BOTH)
- `text_area = tk.Text(...)`: เรากำลังสร้างพื้นที่สำหรับป้อนข้อความโดยใช้ชิ้นส่วน (เรียกว่า widget) ที่ชื่อ `Text` จากกล่องเครื่องมือ `tk` ครับ ส่วน `wrap=tk.WORD` คือการตั้งค่าให้ตัดคำขึ้นบรรทัดใหม่ตามหน่วยของคำ ซึ่งเป็นมารยาทที่ดีเพื่อไม่ให้ประโยคภาษาอังกฤษถูกตัดกลางคำอย่างไม่สวยงาม
- `text_area.pack(...)`: เป็นคำสั่งสำหรับจัดวาง `text_area` ที่สร้างขึ้นลงบน `window` ซึ่งเป็นแม่ของมัน `pack` เป็นวิธีการจัดเลย์เอาต์แบบง่ายๆ และการระบุ `expand=True, fill=tk.BOTH` จะทำให้เกิดการจัดวางที่ชาญฉลาดว่า "ถ้าขนาดหน้าต่างเปลี่ยนไป พื้นที่ข้อความก็จะขยายตามให้เต็มพื้นที่ทั้งแนวตั้งและแนวนอน"
④ สร้างกล่องรวบรวมคำสั่ง (ฟังก์ชัน)
ในที่สุดก็มาถึงหัวใจของแอปนี้ นั่นคือการอธิบายกระบวนการทำงานเฉพาะอย่าง "การเปิดไฟล์" และ "การบันทึกไฟล์" ครับ กระบวนการเหล่านี้ถูกกำหนดไว้ในรูปแบบของ ฟังก์ชัน ซึ่งเปรียบเสมือน "กล่องที่มีประโยชน์สำหรับรวบรวมคำสั่ง" ครับ
การบันทึกไฟล์: ฟังก์ชัน `save_file()`
def save_file():
"""ฟังก์ชันสำหรับบันทึกไฟล์"""
file_path = filedialog.asksaveasfilename(
defaultextension=".txt",
filetypes=[("ไฟล์ข้อความ", "*.txt"), ("ไฟล์ทั้งหมด", "*.*")]
)
if not file_path:
return
try:
with open(file_path, 'w', encoding='utf-8') as file:
text_content = text_area.get(1.0, tk.END)
file.write(text_content)
except Exception as e:
print(f"เกิดข้อผิดพลาด: {e}")
โค้ดส่วนนี้มีประเด็นสำคัญอยู่มากมายครับ
- `filedialog.asksaveasfilename(...)`: นี่คือคำสั่งสำหรับแสดงกล่องโต้ตอบ "บันทึกเป็น" ครับ ตำแหน่งที่จัดเก็บไฟล์ที่ผู้ใช้เลือก (หรือที่อยู่ของไฟล์) จะถูกเก็บไว้ในตัวแปรที่ชื่อ `file_path` ครับ
- `if not file_path: return`: หากผู้ใช้กดปุ่ม "ยกเลิก" ในกล่องโต้ตอบ `file_path` จะมีค่าเป็นว่าง ในกรณีนั้น บรรทัดสำคัญนี้จะทำให้ฟังก์ชันสิ้นสุดการทำงานโดยไม่ทำอะไรเลย
- `with open(file_path, 'w', encoding='utf-8') as file:`: นี่คือหัวใจของการจัดการไฟล์!
- `open()`: คำสั่งสำหรับเปิดไฟล์ตามตำแหน่งที่ระบุในโหมดที่กำหนด
- `'w'`: หมายถึงโหมด `write` (เขียน) ถ้าไม่มีไฟล์อยู่จะสร้างขึ้นมาใหม่ ถ้ามีอยู่แล้วจะเขียนทับ
- `encoding='utf-8'`: เป็นคาถาที่สำคัญสุดๆ เพื่อป้องกันปัญหาตัวอักษรเพี้ยน (ภาษาต่างดาว) โดยระบุให้ใช้ "UTF-8" ซึ่งเป็นรูปแบบการเข้ารหัสตัวอักษรมาตรฐานที่สามารถจัดการกับภาษาเกือบทั้งหมดในโลกได้อย่างถูกต้อง ถ้าไม่เขียนบรรทัดนี้ อาจทำให้ภาษาไทยไม่สามารถบันทึกได้อย่างถูกต้องครับ
- `with ... as file:`: การใช้ синтаксис นี้จะช่วยให้ไฟล์ถูกปิดโดยอัตโนมัติหลังจากที่การทำงานในบล็อกนี้เสร็จสิ้น การลืมปิดไฟล์อาจทำให้เกิดปัญหาเช่นหน่วยความจำรั่วไหลได้ ดังนั้นนี่จึงเป็นวิธีการเขียนที่ปลอดภัยและแนะนำเป็นอย่างยิ่งครับ (แนะนำในเอกสารทางการเช่นกัน)
- `text_area.get(1.0, tk.END)`: ใช้สำหรับดึงข้อความทั้งหมดที่ถูกป้อนเข้ามาในพื้นที่ข้อความ
- `file.write(text_content)`: ใช้สำหรับเขียนข้อความที่ดึงมาลงในไฟล์ที่เปิดอยู่
ในทำนองเดียวกัน ฟังก์ชัน `open_file()` ก็แค่ใช้ `'r'` (โหมด read: อ่าน) เพื่ออ่านเนื้อหาของไฟล์แล้วนำมาแสดงในพื้นที่ข้อความเท่านั้นเองครับ หลักการทำงานแทบจะเหมือนกันเลย!
ขั้นตอนที่ 3: ขั้นประยุกต์! มาดัดแปลงให้เป็น Notepad ในแบบของคุณกัน
เมื่อเข้าใจหลักการพื้นฐานแล้ว ต่อไปเรามาทำให้มันน่าสนใจยิ่งขึ้นกันเถอะ! แค่เพิ่มโค้ดนิดหน่อยก็สามารถติดตั้งฟังก์ชันที่มีประโยชน์ได้แล้วครับ
ตัวอย่างการดัดแปลง ①: ทำให้เป็นดีไซน์สไตล์โหมดมืด
โหมดมืดที่กำลังเป็นที่นิยมในปัจจุบัน มาลองเปลี่ยนดีไซน์ให้ถนอมสายตากันดูครับ แค่ระบุสีพื้นหลังและสีตัวอักษรในส่วนที่สร้าง `window` กับ `text_area` เท่านั้นเอง
# สร้างหน้าต่างหลัก
window = tk.Tk()
window.title("Notepad โหมดมืด")
window.geometry("600x400")
window.config(bg="#2d2d2d") # เพิ่มสีพื้นหลังของหน้าต่าง
# สร้างพื้นที่สำหรับป้อนข้อความ
text_area = tk.Text(
window,
wrap=tk.WORD,
bg="#1e1e1e", # สีพื้นหลังของพื้นที่ข้อความ
fg="#dcdcdc", # สีตัวอักษร
insertbackground="#ffffff" # สีของเคอร์เซอร์
)
text_area.pack(expand=True, fill=tk.BOTH)
เพียงเท่านี้ ก็ได้บรรยากาศที่ทันสมัยขึ้นมาทันทีเลยใช่ไหมล่ะครับ!
ตัวอย่างการดัดแปลง ②: เพิ่มคีย์ลัด
การเปิดเมนูทุกครั้งมันน่ารำคาญใช่ไหมครับ มาทำให้สามารถบันทึกด้วย "Ctrl + S" และเปิดด้วย "Ctrl + O" กันเถอะครับ ตอนที่เพิ่มรายการลงในเมนู ให้ระบุคีย์ลัดด้วย `accelerator` แล้วใช้ `window.bind` เพื่อเชื่อมโยงการทำงานของคีย์บอร์ดเข้ากับฟังก์ชัน
ก่อนอื่น ให้เปลี่ยนส่วนของการสร้างเมนูเป็นแบบนี้ครับ
# สร้างเมนู "ไฟล์"
file_menu = tk.Menu(menu_bar, tearoff=0)
menu_bar.add_cascade(label="ไฟล์", menu=file_menu)
# ใช้ accelerator เพื่อแสดงคีย์ลัดเป็นคำใบ้
file_menu.add_command(label="เปิด...", command=open_file, accelerator="Ctrl+O")
file_menu.add_command(label="บันทึกเป็น...", command=save_file, accelerator="Ctrl+S")
file_menu.add_separator()
file_menu.add_command(label="ออก", command=window.quit)
จากนั้น ให้เพิ่มโค้ดสำหรับเชื่อมโยงการทำงานของคีย์เข้ากับฟังก์ชันไว้ก่อน `window.mainloop()` ครับ
# การผูกคีย์ลัด
# ใช้ lambda เพื่อรับอาร์กิวเมนต์ของอีเวนต์
window.bind("<Control-s>", lambda event: save_file())
window.bind("<Control-o>", lambda event: open_file())
# แสดงหน้าต่าง
window.mainloop()
เมธอด `bind` จะเรียกฟังก์ชันเมื่อเกิดอีเวนต์ขึ้น (ในกรณีนี้คือการกดคีย์) แต่ตอนนั้นมันจะส่งข้อมูลเกี่ยวกับอีเวนต์ (อ็อบเจกต์ `event`) มาเป็นอาร์กิวเมนต์ด้วย แต่ฟังก์ชัน `save_file` และ `open_file` ของเราถูกออกแบบมาให้ไม่รับอาร์กิวเมนต์ ดังนั้นเราจึงใช้ `lambda event:` เพื่อทำหน้าที่เป็นตัวกลางในการเพิกเฉยต่ออาร์กิวเมนต์และเรียกฟังก์ชันเป้าหมายแทน เป็นเทคนิคเล็กๆ น้อยๆ ที่ดีเลยใช่ไหมครับ!
ข้อควรระวัง (ไม้เท้ากันหมา)
การจัดการไฟล์เป็นส่วนที่มักเกิดข้อผิดพลาดที่ไม่คาดคิดได้ง่ายครับ ผมเองก็เคยจ้องหน้าจอข้อผิดพลาดแล้วปวดหัวมานับครั้งไม่ถ้วน... แค่รู้ข้อผิดพลาดที่พบบ่อยๆ ไว้ ก็ช่วยให้เราไม่ตื่นตระหนกได้แล้วครับ
- `PermissionError`: จะเกิดขึ้นเมื่อพยายามบันทึกไฟล์ลงในโฟลเดอร์ที่ห้ามการเขียน (เช่น `C:\Program Files`) ให้เลือกบันทึกในที่ที่เรามีสิทธิ์เขียน เช่น บนเดสก์ท็อปหรือในโฟลเดอร์เอกสาร
- `FileNotFoundError`: จะเกิดขึ้นในฟังก์ชัน `open_file` เมื่อระบุไฟล์ที่ไม่มีอยู่จริง ในโค้ดของเราใช้ `filedialog` อยู่แล้ว โดยพื้นฐานจึงไม่น่าจะเกิดขึ้น แต่ก็ควรระวังเมื่อจะดัดแปลงโค้ดครับ
- `UnicodeDecodeError`: จะเกิดขึ้นเมื่อพยายามเปิดไฟล์ที่ไม่สามารถอ่านด้วย `encoding='utf-8'` ได้ (เช่น ไฟล์ข้อความเก่าๆ ที่บันทึกด้วย `Shift_JIS`) นี่เป็นปัญหาที่ค่อนข้างซับซ้อน แต่เบื้องต้นแค่รู้ว่า "บนโลกนี้มีรูปแบบการเข้ารหัสตัวอักษรอยู่หลากหลาย" ก็พอแล้วครับ
ในโค้ดของเรา เราใช้บล็อก `try...except` เพื่อดักจับข้อผิดพลาด ดังนั้นต่อให้เกิดข้อผิดพลาดขึ้น แอปก็จะไม่แครช และจะมีข้อความแสดงข้อผิดพลาดปรากฏขึ้นในคอนโซลแทน นี่ก็เป็นอีกหนึ่งเทคนิคสำคัญในการสร้างโปรแกรมที่ปลอดภัยครับ
สรุป: ความสำเร็จเล็กๆ คือก้าวที่ยิ่งใหญ่สู่ขั้นต่อไป
お疲れ様でした!今回はPythonの`Tkinter`を使って、ファイル保存機能付きのシンプルなメモ帳アプリを作成しました。
コピペから始めて、その仕組みを理解し、最後は自分で改造するところまで体験していただけたでしょうか。「自分で書いたコードが、目に見える形で動く」という経験は、何物にも代えがたい喜びであり、プログラミング学習を続ける上で最高のモチベーションになります。
今回作ったアプリは、ほんの始まりに過ぎません。検索機能、文字数カウント、自動保存など、アイデア次第でいくらでも機能を追加できます。ぜひ、この記事を土台にして、あなただけのオリジナルアプリ開発に挑戦してみてください!
ไปยังขั้นตอนถัดไป
เมื่อเข้าใจพื้นฐานของแอป GUI แล้ว ต่อไปมาลองควบคุม "เวลา" กันดูไหมครับ? ในบทความหน้า เราจะอธิบายวิธีใช้โมดูล `time` ของ Python เพื่อสร้างแอปจับเวลาที่สามารถแจ้งเตือนเมื่อถึงเวลาที่กำหนด มาท้าทายตัวเองด้วยการสร้างเครื่องมือที่มีประโยชน์ในชีวิตประจำวันอย่างนาฬิกาปลุกหรือตัวจับเวลา Pomodoro กันเถอะ!
→ มาสร้างแอปจับเวลาด้วย Python กันเถอะ (โมดูล time)ของแถม: โค้ด Python ฉบับสมบูรณ์ที่พร้อมใช้งาน
นี่คือโค้ด Python ฉบับสมบูรณ์เวอร์ชันสุดท้ายที่รวมเอาตัวอย่างการประยุกต์ใช้ดีไซน์สไตล์โหมดมืดและคีย์ลัดที่อธิบายไว้ในบทความนี้ทั้งหมดแล้วครับ แค่คัดลอกโค้ดนี้ไปใช้ ก็จะได้แอป Notepad ที่มีฟังก์ชันครบครันไปใช้ได้ทันที!
<?php
/*
นี่คือโค้ด Python ไม่ใช่ไฟล์ PHP ที่จะรันบนเว็บเซิร์ฟเวอร์
กรุณาเปลี่ยนนามสกุลเป็น .py แล้วรันด้วยตัวแปลภาษา Python
ตัวอย่าง: python your_file_name.py
*/
?>
import tkinter as tk
import tkinter.filedialog as filedialog
def save_file():
"""ฟังก์ชันสำหรับบันทึกไฟล์"""
file_path = filedialog.asksaveasfilename(
defaultextension=".txt",
filetypes=[("ไฟล์ข้อความ", "*.txt"), ("ไฟล์ทั้งหมด", "*.*")]
)
if not file_path:
return
try:
with open(file_path, 'w', encoding='utf-8') as file:
text_content = text_area.get(1.0, tk.END)
file.write(text_content)
except Exception as e:
# ตามหลักแล้วควรบันทึกใน로그หรือแจ้งผู้ใช้ผ่านไดอะล็อกจะดีกว่า
print(f"เกิดข้อผิดพลาด: {e}")
window.title(f"ข้อผิดพลาด: {e}")
def open_file():
"""ฟังก์ชันสำหรับเปิดไฟล์"""
file_path = filedialog.askopenfilename(
filetypes=[("ไฟล์ข้อความ", "*.txt"), ("ไฟล์ทั้งหมด", "*.*")]
)
if not file_path:
return
try:
with open(file_path, 'r', encoding='utf-8') as file:
text_content = file.read()
text_area.delete(1.0, tk.END)
text_area.insert(tk.END, text_content)
window.title(f"Notepad - {file_path}")
except Exception as e:
print(f"เกิดข้อผิดพลาด: {e}")
window.title(f"ข้อผิดพลาด: {e}")
# --- การตั้งค่า GUI ---
# สร้างหน้าต่างหลัก
window = tk.Tk()
window.title("Notepad ขั้นสูง")
window.geometry("800x600")
window.config(bg="#2d2d2d") # สีพื้นหลังของหน้าต่าง
# สร้างพื้นที่สำหรับป้อนข้อความ
text_area = tk.Text(
window,
wrap=tk.WORD,
bg="#1e1e1e", # สีพื้นหลังของพื้นที่ข้อความ
fg="#dcdcdc", # สีตัวอักษร
insertbackground="#ffffff", # สีของเคอร์เซอร์ (สีขาวเพื่อให้มองเห็นง่าย)
undo=True, # เปิดใช้งานฟังก์ชัน Undo/Redo
autoseparators=True
)
text_area.pack(expand=True, fill=tk.BOTH, padx=5, pady=5)
# สร้างแถบเมนู
menu_bar = tk.Menu(window)
window.config(menu=menu_bar)
# สร้างเมนู "ไฟล์"
file_menu = tk.Menu(menu_bar, tearoff=0, bg="#2d2d2d", fg="#dcdcdc")
menu_bar.add_cascade(label="ไฟล์", menu=file_menu)
file_menu.add_command(label="เปิด...", command=open_file, accelerator="Ctrl+O")
file_menu.add_command(label="บันทึกเป็น...", command=save_file, accelerator="Ctrl+S")
file_menu.add_separator()
file_menu.add_command(label="ออก", command=window.quit)
# การผูกคีย์ลัด (ใช้ lambda เพื่อเพิกเฉยต่ออาร์กิวเมนต์ของอีเวนต์)
window.bind("<Control-s>", lambda event: save_file())
window.bind("<Control-o>", lambda event: open_file())
window.bind("<Control-S>", lambda event: save_file()) # รองรับการกด Shift พร้อมกันด้วย
window.bind("<Control-O>", lambda event: open_file()) # รองรับการกด Shift พร้อมกันด้วย
# เริ่มลูปการแสดงผลของหน้าต่าง
window.mainloop()