使用 python 中的 Tkinter 开发记事本
记事本是我们日常办公和生活中常用的工具之一。我们可以使用 python 自带的 GUI 模块 Tkinter 来开发一个简单的记事本应用。下面我们就来学习一下 Tkinter 开发记事本的实现过程。
Tkinter 环境搭建
首先,我们需要安装 python 的 Tkinter 模块。Tkinter 模块是 python 内置的 GUI 库,无需额外安装。
我们可以使用下面的命令在终端中检查是否安装 Tkinter:
python -m tkinter
如果出现了一个 TK 窗口,说明我们电脑中已经安装了 Tkinter。
UI 设计
我们需要设计一个简单的 UI 界面,包括菜单栏、工具栏和文本编辑区域,以编写和保存文档。可以参考如下的设计:
我们的记事本界面包括:
- 菜单栏:文件、编辑、格式和帮助四个菜单项
- 工具栏:包括新建、打开、保存、剪切、复制、粘贴按钮
- 文本编辑区域:可以输入文本和进行编辑
基本代码
在开始编写记事本应用之前,我们需要先导入需要的库:sys、os、Tkinter。
import sys
import os
import tkinter as tk
接下来,我们可以创建一个名为 NotePad 的类,用于实现记事本应用。
class NotePad:
def __init__(self):
self.root = tk.Tk()
self.root.title("记事本")
self.root.geometry("600x400")
self.textarea = tk.Text(self.root)
self.textarea.pack(expand=True, fill="both")
self.menubar = tk.Menu(self.root)
self.filemenu = tk.Menu(self.menubar, tearoff=0)
self.filemenu.add_command(label="新建", accelerator="Ctrl+N", command=self.new_file)
self.filemenu.add_command(label="打开", accelerator="Ctrl+O", command=self.open_file)
self.filemenu.add_command(label="保存", accelerator="Ctrl+S", command=self.save_file)
self.filemenu.add_command(label="另存为", command=self.saveas_file)
self.filemenu.add_separator()
self.filemenu.add_command(label="退出", accelerator="Alt+F4", command=self.exit)
self.menubar.add_cascade(label="文件", menu=self.filemenu)
self.editmenu = tk.Menu(self.menubar, tearoff=0)
self.editmenu.add_command(label="剪切", accelerator="Ctrl+X", command=self.cut_text)
self.editmenu.add_command(label="复制", accelerator="Ctrl+C", command=self.copy_text)
self.editmenu.add_command(label="粘贴", accelerator="Ctrl+V", command=self.paste_text)
self.editmenu.add_separator()
self.editmenu.add_command(label="撤销", accelerator="Ctrl+Z", command=self.undo)
self.editmenu.add_command(label="重做", accelerator="Ctrl+Y", command=self.redo)
self.menubar.add_cascade(label="编辑", menu=self.editmenu)
self.formatmenu = tk.Menu(self.menubar, tearoff=0)
self.menubar.add_cascade(label="格式", menu=self.formatmenu)
self.helpmenu = tk.Menu(self.menubar, tearoff=0)
self.helpmenu.add_command(label="帮助", command=self.help)
self.helpmenu.add_separator()
self.helpmenu.add_command(label="关于记事本", command=self.about)
self.menubar.add_cascade(label="帮助", menu=self.helpmenu)
self.root.config(menu=self.menubar)
在上面的代码中,我们定义了一个 NotePad 类,并使用 TKinter 创建了一个窗口。在该窗口中,我们添加了一个文本编辑区域、菜单栏和工具栏。
接下来,我们来逐一解释每个部分的代码:
- 创建主窗口
self.root = tk.Tk()
self.root.title("记事本")
self.root.geometry("600x400")
我们使用 tk.Tk()
创建了一个窗口,并将窗口标题设置为“记事本”。我们还设置了窗口的大小为 600x400
像素。
- 创建文本编辑区域
self.textarea = tk.Text(self.root)
self.textarea.pack(expand=True, fill="both")
我们使用 tk.Text()
创建了一个文本编辑区域,并将其添加到窗口中。我们还使用 pack()
函数将其铺满整个窗口。
- 创建菜单栏
self.menubar = tk.Menu(self.root)
我们使用 tk.Menu()
创建了一个菜单栏,用于添加菜单项。
- 文件菜单
self.filemenu = tk.Menu(self.menubar, tearoff=0)
self.filemenu.add_command(label="新建", accelerator="Ctrl+N", command=self.new_file)
self.filemenu.add_command(label="打开", accelerator="Ctrl+O", command=self.open_file)
self.filemenu.add_command(label="保存", accelerator="Ctrl+S", command=self.save_file)
self.filemenu.add_command(label="另存为", command=self.saveas_file)
self.filemenu.add_separator()
self.filemenu.add_command(label="退出", accelerator="Alt+F4", command=self.exit)
self.menubar.add_cascade(label="文件", menu=self.filemenu)
我们使用 tk.Menu()
创建了一个文件菜单,并使用 add_command()
函数添加了文件菜单项,例如“新建”、“打开”、“保存”、“另存为”和“退出”。我们还使用 add_separator()
函数添加了分隔符。
- 编辑菜单
self.editmenu = tk.Menu(self.menubar, tearoff=0)
self.editmenu.add_command(label="剪切", accelerator="Ctrl+X", command=self.cut_text)
self.editmenu.add_command(label="复制", accelerator="Ctrl+C", command=self.copy_text)
self.editmenu.add_command(label="粘贴", accelerator="Ctrl+V", command=self.paste_text)
self.editmenu.add_separator()
self.editmenu.add_command(label="撤销", accelerator="Ctrl+Z", command=self.undo)
self.editmenu.add_command(label="重做", accelerator="Ctrl+Y", command=self.redo)
self.menubar.add_cascade(label="编辑", menu=self.editmenu)
我们使用 tk.Menu()
创建了一个编辑菜单,并使用 add_command()
函数添加了编辑菜单项,例如“剪切”、“复制”、“粘贴”、“撤销”和“重做”。我们还使用 add_separator()
函数添加了分隔符。
- 格式菜单
self.formatmenu = tk.Menu(self.menubar, tearoff=0)
self.menubar.add_cascade(label="格式", menu=self.formatmenu)
我们使用 tk.Menu()
创建了一个格式菜单,并将其添加到菜单栏中。
- 帮助菜单
self.helpmenu = tk.Menu(self.menubar, tearoff=0)
self.helpmenu.add_command(label="帮助", command=self.help)
self.helpmenu.add_separator()
self.helpmenu.add_command(label="关于记事本", command=self.about)
self.menubar.add_cascade(label="帮助", menu=self.helpmenu)
我们使用 tk.Menu()
创建了一个帮助菜单,并使用 add_command()
函数添加了“帮助”和“关于记事本”菜单项。我们还使用 add_separator()
函数添加了分隔符。
功能实现
在上面的代码中,我们已经完成了记事本的 UI 设计,包括窗口、菜单栏、工具栏和文本编辑区域等。
接下来,我们需要实现这些菜单项和工具栏按钮的功能。
新建菜单项和工具栏按钮
def new_file(self, *args):
self.textarea.delete(1.0, tk.END)
self.filename = ''
def new_file_toolbar(self, event=None):
self.new_file()
我们定义了 new_file()
函数,当点击“新建”菜单项时将调用该函数。在该函数中,我们使用 delete()
函数删除文本编辑区域中的所有内容,并将当前文件名设置为空。
我们还定义了一个 new_file_toolbar()
函数,用于点击工具栏中的“新建”按钮调用。如果不想在工具栏中添加该按钮,可以省略这个函数。
打开菜单项和工具栏按钮
def open_file(self, *args):
self.filename = tk.filedialog.askopenfilename(defaultextension=".txt",
filetypes=[("All Files", "*.*"),
("Text Files", "*.txt"),
("Python Files", "*.py")])
if self.filename:
self.textarea.delete(1.0, tk.END)
with open(self.filename, "r") as f:
self.textarea.insert(1.0, f.read())
def open_file_toolbar(self, event=None):
self.open_file()
我们定义了 open_file()
函数,当点击“打开”菜单项时将调用该函数。在该函数中,我们使用 askopenfilename()
函数打开文件对话框,用于选择要打开的文件。如果用户选择了一个文件,我们将使用 with open()
语句读取文件的内容,并使用 insert()
函数将文件内容插入到文本编辑区域中。
我们还定义了一个 open_file_toolbar()
函数,用于点击工具栏中的“打开”按钮调用。如果不想在工具栏中添加该按钮,可以省略这个函数。
保存菜单项和工具栏按钮
def save_file(self, *args):
if self.filename:
with open(self.filename, "w") as f:
f.write(self.textarea.get(1.0, tk.END))
else:
self.saveas_file()
def save_file_toolbar(self, event=None):
self.save_file()
我们定义了 save_file()
函数,当点击“保存”菜单项时将调用该函数。在该函数中,如果有一个当前打开的文件,我们使用 with open()
语句将文本编辑区域的内容写入该文件。如果没有当前打开的文件,则调用 saveas_file()
函数,另存为一个新文件。
我们还定义了一个 save_file_toolbar()
函数,用于点击工具栏中的“保存”按钮调用。如果不想在工具栏中添加该按钮,可以省略这个函数。
另存为菜单项
def saveas_file(self):
self.filename = tk.filedialog.asksaveasfilename(defaultextension=".txt",
filetypes=[("All Files", "*.*"),
("Text Files", "*.txt"),
("Python Files", "*.py")])
if self.filename:
with open(self.filename, "w") as f:
f.write(self.textarea.get(1.0, tk.END))
我们定义了 saveas_file()
函数,当点击“另存为”菜单项时将调用该函数。在该函数中,我们使用 asksaveasfilename()
函数打开文件对话框,用于选择要另存为的文件。如果用户选择了一个文件,我们将使用 with open()
语句将文本编辑区域的内容写入该文件。
退出菜单项
def exit(self, *args):
self.root.destroy()
我们定义了 exit()
函数,当点击“退出”菜单项时将调用该函数。在该函数中,我们使用 root.destroy()
函数关闭应用程序窗口。
剪切、复制和粘贴菜单项和工具栏按钮
def cut_text(self):
self.textarea.event_generate("<<Cut>>")
def copy_text(self):
self.textarea.event_generate("<<Copy>>")
def paste_text(self):
self.textarea.event_generate("<<Paste>>")
我们定义了 cut_text()
、copy_text()
和 paste_text()
函数,用于执行剪切、复制和粘贴操作。在这些函数中,我们使用 event_generate()
函数来模拟执行相应的操作。
撤销和重做菜单项和工具栏按钮
def undo(self, *args):
try:
self.textarea.edit_undo()
except:
pass
def redo(self, *args):
try:
self.textarea.edit_redo()
except:
pass
我们定义了 undo()
和 redo()
函数,用于执行撤销和重做操作。在这些函数中,我们使用 edit_undo()
和 edit_redo()
函数执行相应的操作。我们还使用了 try...except
语句来处理当撤销或重做操作不可用时的异常情况。
帮助和关于记事本菜单项
def help(self):
messagebox.showinfo("帮助", "这是一个简单的记事本应用程序。")
def about(self):
messagebox.showinfo("关于记事本", "这是一个由 Python 和 Tkinter 制作的记事本应用程序。")
我们定义了 help()
和 about()
函数,用于显示帮助和关于记事本的信息。在这些函数中,我们使用 showinfo()
函数来显示信息框。
绑定快捷键和工具栏按钮
def bind_shortcuts(self):
self.root.bind("<Control-n>", self.new_file_toolbar)
self.root.bind("<Control-o>", self.open_file_toolbar)
self.root.bind("<Control-s>", self.save_file_toolbar)
def add_toolbar(self):
self.toolbar = tk.Frame(self.root, bd=1, relief=tk.RAISED)
self.toolbar.pack(side=tk.TOP, fill=tk.X)
new_icon = tk.PhotoImage(file="icons/new.gif")
new_button = tk.Button(self.toolbar, image=new_icon, command=self.new_file)
new_button.image = new_icon
new_button.pack(side=tk.LEFT, padx=2, pady=2)
open_icon = tk.PhotoImage(file="icons/open.gif")
open_button = tk.Button(self.toolbar, image=open_icon, command=self.open_file)
open_button.image = open_icon
open_button.pack(side=tk.LEFT, padx=2, pady=2)
save_icon = tk.PhotoImage(file="icons/save.gif")
save_button = tk.Button(self.toolbar, image=save_icon, command=self.save_file)
save_button.image = save_icon
save_button.pack(side=tk.LEFT, padx=2, pady=2)
cut_icon = tk.PhotoImage(file="icons/cut.gif")
cut_button = tk.Button(self.toolbar, image=cut_icon, command=self.cut_text)
cut_button.image = cut_icon
cut_button.pack(side=tk.LEFT, padx=2, pady=2)
copy_icon = tk.PhotoImage(file="icons/copy.gif")
copy_button = tk.Button(self.toolbar, image=copy_icon, command=self.copy_text)
copy_button.image = copy_icon
copy_button.pack(side=tk.LEFT, padx=2, pady=2)
paste_icon = tk.PhotoImage(file="icons/paste.gif")
paste_button = tk.Button(self.toolbar, image=paste_icon, command=self.paste_text)
paste_button.image = paste_icon
paste_button.pack(side=tk.LEFT, padx=2, pady=2)
我们定义了 bind_shortcuts()
函数,用于将快捷键绑定到相应的菜单项和工具栏按钮上。在这个函数中,我们使用 bind()
函数来绑定 Control+N
、Control+O
和 Control+S
到新建、打开和保存操作上。
我们也定义了 add_toolbar()
函数,用于向应用程序窗口添加工具栏。在这个函数中,我们使用 tk.Frame()
函数创建了一个框架,并将其添加到应用程序窗口的顶部。然后,我们使用 tk.PhotoImage()
函数加载了工具栏按钮的图标,并将它们添加到工具栏中。每个按钮都使用 tk.Button()
函数创建,并指定了对应的命令函数。
最后,我们需要修改 __init__()
函数,以调用新定义的函数:
def __init__(self, root):
self.root = root
self.filename = ''
self.create_widgets()
self.bind_shortcuts()
self.add_toolbar()
现在,我们已经实现了记事本应用程序的基本功能,用户可以使用菜单项、工具栏按钮和快捷键来执行各种操作。完整代码如下: