[Python教學] Tkinter:實戰專案 - 打造簡單記事本

更新於 發佈於 閱讀時間約 18 分鐘

嘿,大家好!上篇教學文章我們做出了一個待辦事項清單,已經有點小工具的感覺了吧?今天我們要再升級,來做個「簡單記事本」。這個專案不只可以寫東西,還能存檔、開檔,甚至換字體大小,感覺就像自己寫了個迷你軟體!


專案目標

我們的記事本預計會實做以下功能:

  1. 文字區:可以打字的地方,像個大輸入框。
  2. 選單:有「檔案」(存檔、開檔、離開)和「格式」(調字體大小)。
  3. 儲存與開啟:把寫的東西存成檔案,或開舊檔案繼續編輯。
  4. 簡單美化:用點 ttk 讓它看起來不那麼陽春。


基本架構:搭個視窗

先把視窗和主要元件放進去:

import tkinter as tk
from tkinter import ttk, messagebox, filedialog

class NotepadApp:
def __init__(self, window):
self.window = window
self.window.title("簡單記事本")
self.window.geometry("600x400")

# 文字區
self.text = tk.Text(self.window, wrap="word", font=("微軟正黑體", 12))
self.text.pack(expand=True, fill="both", padx=10, pady=10)

# 選單列
self.menu_bar = tk.Menu(self.window)
self.window.config(menu=self.menu_bar)

# 檔案選單
file_menu = tk.Menu(self.menu_bar, tearoff=0)
self.menu_bar.add_cascade(label="檔案", menu=file_menu)
file_menu.add_command(label="開啟", command=self.open_file)
file_menu.add_command(label="儲存", command=self.save_file)
file_menu.add_separator()
file_menu.add_command(label="離開", command=self.quit)

# 格式選單
format_menu = tk.Menu(self.menu_bar, tearoff=0)
self.menu_bar.add_cascade(label="格式", menu=format_menu)
format_menu.add_command(label="字體大小", command=self.change_font_size)

def open_file(self):
pass # 先留空,等等填

def save_file(self):
pass

def change_font_size(self):
pass

def quit(self):
pass

# 啟動程式
window = tk.Tk()
app = NotepadApp(window)
window.mainloop()

跑一下看看!有個視窗,裡面是大大的文字區,上面有「檔案」和「格式」選單,點下去還沒反應,因為功能還沒寫。

raw-image


  • tk.Text:這是大輸入框,比 Entry 強,能多行編輯,wrap="word" 讓換行更自然。
  • pack(expand=True, fill="both"):讓文字區填滿視窗,隨視窗大小調整。


功能實作:讓它動起來

現在來填滿那些空函式,讓記事本真的能用!

1. 儲存檔案

點「儲存」時,跳出檔案對話框,讓你選地方存:

def save_file(self):
file_path = filedialog.asksaveasfilename(
defaultextension=".txt",
filetypes=[("文字檔案", "*.txt"), ("所有檔案", "*.*")]
)
if file_path:
try:
with open(file_path, "w", encoding="utf-8") as file:
file.write(self.text.get("1.0", tk.END).strip())
self.window.title(f"簡單記事本 - {file_path}")
except Exception as e:
messagebox.showerror("錯誤", f"儲存失敗!{e}")
raw-image
  • filedialog.asksaveasfilename:跳出儲存對話框,選檔案路徑。
  • self.text.get("1.0", tk.END):從第一行第一個字(1.0)抓到最後,strip() 去掉多餘換行。
  • 更新標題顯示檔案路徑,讓你知道存檔在哪裡。


2. 開啟檔案

點「開啟」時,選檔案讀進文字區:

def open_file(self):
file_path = filedialog.askopenfilename(
filetypes=[("文字檔案", "*.txt"), ("所有檔案", "*.*")]
)
if file_path:
try:
with open(file_path, "r", encoding="utf-8") as file:
content = file.read()
self.text.delete("1.0", tk.END) # 清空文字區
self.text.insert("1.0", content) # 放進新內容
self.window.title(f"簡單記事本 - {file_path}")
except Exception as e:
messagebox.showerror("錯誤", f"開啟失敗!{e}")
raw-image
  • filedialog.askopenfilename:選檔案的對話框。
  • delete 和 insert:清空再填入,保持乾淨。


3. 調整字體大小

點「字體大小」時,跳個小視窗讓你選:

def change_font_size(self):
size_window = tk.Toplevel(self.window) # 跳出小視窗
size_window.title("字體大小")
size_window.geometry("200x100")

tk.Label(size_window, text="選個大小:").pack(pady=5)
size_var = tk.IntVar(value=12) # 預設 12
ttk.Spinbox(size_window, from_=8, to=30, textvariable=size_var).pack(pady=5)

def apply_size():
new_size = size_var.get()
self.text.config(font=("微軟正黑體", new_size))
size_window.destroy()

ttk.Button(size_window, text="確定", command=apply_size).pack(pady=5)
raw-image
  • Toplevel:跳出獨立小視窗,不影響主視窗。
  • Spinbox:數字選擇器,範圍 8 到 30。
  • config(font=...):動態改文字區字體。


4. 離開前提醒

關視窗前先做確認,避免寫好的訊息沒有存檔到:

def quit(self):
if messagebox.askokcancel("離開", "確定要關嗎?沒存的會不見喔!"):
self.window.destroy()

# 在 __init__ 最後加這行
self.window.protocol("WM_DELETE_WINDOW", self.quit)
raw-image


完整程式碼

把上面的教學全部合起來,完成我們的記事本:

import tkinter as tk
from tkinter import ttk, messagebox, filedialog

class NotepadApp:
def __init__(self, window):
self.window = window
self.window.title("簡單記事本")
self.window.geometry("600x400")

# 文字區
self.text = tk.Text(self.window, wrap="word", font=("微軟正黑體", 12))
self.text.pack(expand=True, fill="both", padx=10, pady=10)

# 選單列
self.menu_bar = tk.Menu(self.window)
self.window.config(menu=self.menu_bar)

# 檔案選單
file_menu = tk.Menu(self.menu_bar, tearoff=0)
self.menu_bar.add_cascade(label="檔案", menu=file_menu)
file_menu.add_command(label="開啟", command=self.open_file)
file_menu.add_command(label="儲存", command=self.save_file)
file_menu.add_separator()
file_menu.add_command(label="離開", command=self.quit)

# 格式選單
format_menu = tk.Menu(self.menu_bar, tearoff=0)
self.menu_bar.add_cascade(label="格式", menu=format_menu)
format_menu.add_command(label="字體大小", command=self.change_font_size)

# 關閉提醒
self.window.protocol("WM_DELETE_WINDOW", self.quit)

def save_file(self):
file_path = filedialog.asksaveasfilename(
defaultextension=".txt",
filetypes=[("文字檔案", "*.txt"), ("所有檔案", "*.*")]
)
if file_path:
try:
with open(file_path, "w", encoding="utf-8") as file:
file.write(self.text.get("1.0", tk.END).strip())
self.window.title(f"簡單記事本 - {file_path}")
except Exception as e:
messagebox.showerror("錯誤", f"儲存失敗!{e}")

def open_file(self):
file_path = filedialog.askopenfilename(
filetypes=[("文字檔案", "*.txt"), ("所有檔案", "*.*")]
)
if file_path:
try:
with open(file_path, "r", encoding="utf-8") as file:
content = file.read()
self.text.delete("1.0", tk.END)
self.text.insert("1.0", content)
self.window.title(f"簡單記事本 - {file_path}")
except Exception as e:
messagebox.showerror("錯誤", f"開啟失敗!{e}")

def change_font_size(self):
size_window = tk.Toplevel(self.window)
size_window.title("字體大小")
size_window.geometry("200x100")

tk.Label(size_window, text="選個大小:").pack(pady=5)
size_var = tk.IntVar(value=12)
ttk.Spinbox(size_window, from_=8, to=30, textvariable=size_var).pack(pady=5)

def apply_size():
new_size = size_var.get()
self.text.config(font=("微軟正黑體", new_size))
size_window.destroy()

ttk.Button(size_window, text="確定", command=apply_size).pack(pady=5)

def quit(self):
if messagebox.askokcancel("離開", "確定要關嗎?沒存的會不見喔!"):
self.window.destroy()

# 啟動程式
window = tk.Tk()
app = NotepadApp(window)
window.mainloop()

跑跑看!寫點東西,存個檔案,再開回來看看,字體大小也能調,是不是超有成就感?


小挑戰:升級你的記事本

課後小挑戰,試試對記事本做以下升級:

  1. 加個「新建」選項,清空文字區並重設標題。
  2. 在文字區右邊加滾動條(用 Scrollbar)。
  3. 加個「關於」選項,點下去跳出你的名字和版本號(像「by 你的大名, v1.0」)。
raw-image


這篇小結

今天我們從零打造了一個簡單記事本,能存檔能讀檔,還能調字體,已經很像個實用的工具了吧?怎麼樣,覺得 Tkinter 的潛力有沒有被你挖出來?這篇結束後,可以自己試著做些其他的小專案,像計算器、畫板之類的!


留言
avatar-img
留言分享你的想法!
avatar-img
追極光的北極熊|軟體工程師的小天地
12會員
163內容數
歡迎來到我的部落格!這裡記錄了軟體工程師的日常生活點滴,並分享程式設計與演算法的實用教學。無論你是初學者還是有經驗的開發者,都能在這裡找到深入淺出的技術解析與實戰技巧。此外,我也會分享工作中的心路歷程與學習心得,讓你不僅學到技術,更能瞭解軟體開發的實際應用與挑戰。希望透過這個平台,能與你共同成長,激發對技術的熱情!
2025/04/28
當我們開發程式時,功能能正常運作固然重要,但在資料量變大或執行時間變長時,效能就成為不可忽視的一環。尤其在 Web 應用、資料分析或科學運算中,程式跑得快與否,直接影響使用者體驗與系統成本。
2025/04/28
當我們開發程式時,功能能正常運作固然重要,但在資料量變大或執行時間變長時,效能就成為不可忽視的一環。尤其在 Web 應用、資料分析或科學運算中,程式跑得快與否,直接影響使用者體驗與系統成本。
2025/04/16
嘿,大家好!走到這一步,我們已經玩過 Tkinter 的基本招式、佈局、事件處理,還搞了些進階元件,應該有點信心了吧?今天我們要把這些功夫練成一套連招,來做個實用的「待辦事項清單」(To-Do List),順便聊聊怎麼把程式寫得更漂亮、更好用。準備好了嗎?這就上場啦!
2025/04/16
嘿,大家好!走到這一步,我們已經玩過 Tkinter 的基本招式、佈局、事件處理,還搞了些進階元件,應該有點信心了吧?今天我們要把這些功夫練成一套連招,來做個實用的「待辦事項清單」(To-Do List),順便聊聊怎麼把程式寫得更漂亮、更好用。準備好了嗎?這就上場啦!
2025/04/10
嘿,大家好!到目前為止,我們已經能讓視窗動起來,還能抓資料、處理按鈕點擊,感覺有點像回事了吧?不過,單靠標籤、按鈕、輸入框有點單調,今天我們要來玩點進階的東西,像是勾選框、選單、下拉清單這些,讓你的應用更有「專業感」。
2025/04/10
嘿,大家好!到目前為止,我們已經能讓視窗動起來,還能抓資料、處理按鈕點擊,感覺有點像回事了吧?不過,單靠標籤、按鈕、輸入框有點單調,今天我們要來玩點進階的東西,像是勾選框、選單、下拉清單這些,讓你的應用更有「專業感」。
看更多
你可能也想看
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
嗨!歡迎來到 vocus vocus 方格子是台灣最大的內容創作與知識變現平台,並且計畫持續拓展東南亞等等國際市場。我們致力於打造讓創作者能夠自由發表、累積影響力並獲得實質收益的創作生態圈!「創作至上」是我們的核心價值,我們致力於透過平台功能與服務,賦予創作者更多的可能。 vocus 平台匯聚了
Thumbnail
打開 jupyter notebook 寫一段 python 程式,可以完成五花八門的工作,這是玩程式最簡便的方式,其中可以獲得很多快樂,在現今這種資訊發達的時代,幾乎沒有門檻,只要願意,人人可享用。 下一步,希望程式可以隨時待命聽我吩咐,不想每次都要開電腦,啟動開發環境,只為完成一個重複性高
Thumbnail
打開 jupyter notebook 寫一段 python 程式,可以完成五花八門的工作,這是玩程式最簡便的方式,其中可以獲得很多快樂,在現今這種資訊發達的時代,幾乎沒有門檻,只要願意,人人可享用。 下一步,希望程式可以隨時待命聽我吩咐,不想每次都要開電腦,啟動開發環境,只為完成一個重複性高
Thumbnail
這篇內容,將教你如何開啟新的GameMaker專案,並調整畫面佈局。也會講解,為何建議用英文語系,來進行遊戲開發。
Thumbnail
這篇內容,將教你如何開啟新的GameMaker專案,並調整畫面佈局。也會講解,為何建議用英文語系,來進行遊戲開發。
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
你好,在下最近在學習開發web,學了html css js,也得出一些心得,由於網路上已有許多教學,所以我會著重在如何開發出to do List,以及解釋我寫的程式碼。相關的教學我會直接貼網址。如果我有什麼地方出錯,或者是可以寫得更好,歡迎在下方留言,討論。 首先先介紹我的開發環境: 我用了vs
Thumbnail
成功加入Anytype之後就可以開始探索這一個開源的筆記軟體了^_^ 開始Anytype之前..... 1.刪除所有初始物件 2.思考自己的使用需求 3.不著急學會所有功能
Thumbnail
成功加入Anytype之後就可以開始探索這一個開源的筆記軟體了^_^ 開始Anytype之前..... 1.刪除所有初始物件 2.思考自己的使用需求 3.不著急學會所有功能
Thumbnail
Anytype主要分為四區塊:目錄欄(Widget組成)、主編輯畫面、導航選單、設定區。
Thumbnail
Anytype主要分為四區塊:目錄欄(Widget組成)、主編輯畫面、導航選單、設定區。
Thumbnail
今天來介紹python的函式 函式在python中是非常重要的一環,因為到了後期,程式會越來越複雜。 而函式可以想成是容易管理的小程式,當我們需要使用時,只需呼叫即可。
Thumbnail
今天來介紹python的函式 函式在python中是非常重要的一環,因為到了後期,程式會越來越複雜。 而函式可以想成是容易管理的小程式,當我們需要使用時,只需呼叫即可。
Thumbnail
當我們在撰寫一套系統的時候, 總是會提供一個介面讓使用者來觸發功能模組並回傳使用者所需的請求, 而傳統的安裝包模式總是太侷限, 需要個別主機獨立安裝, 相當繁瑣, 但隨著時代的演進與互聯網的崛起, 大部分的工作都可以藉由網頁端、裝置端來觸發, 而伺服端則是負責接收指令、運算與回傳結果, 雲端
Thumbnail
當我們在撰寫一套系統的時候, 總是會提供一個介面讓使用者來觸發功能模組並回傳使用者所需的請求, 而傳統的安裝包模式總是太侷限, 需要個別主機獨立安裝, 相當繁瑣, 但隨著時代的演進與互聯網的崛起, 大部分的工作都可以藉由網頁端、裝置端來觸發, 而伺服端則是負責接收指令、運算與回傳結果, 雲端
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News