上一篇:【Python】使用tkinter设计开发Windows桌面程序记事本(4)-CSDN博客
下一篇:待羽翼丰满之时,必将是文章更新之日!
本篇文章继承了前面四篇文章,并且实现了新建、保存、另存、打开、页面设置、退出功能。
现阶段我还不能实现打印功能,而新窗口要在最后阶段完成,所有我选择忽略这两个功能。
近期我将暂停本项目进度更新(能力受限),但博客文章不受影响,会不定期发布。
有疑问或建议,欢迎在评论区戳我哟!
?在"记事本项目" --> "code"目录下新建了一个"记事本功能设计_2.py"文件,开始本阶段的项目设计开发,如下图:
导入【记事本项目.code.记事本底座】
导入【记事本项目.code.记事本功能设计_1】
导入【记事本项目.code.记事本_页面设置】
导入【记事本项目.code.记事本_页面设置功能设计_1】
光标位置:行 1 列 1
1editText: ['\n']
2editText: ['\n']
2readText: ['']
...
...
...
光标位置:行 7 列 16
1editText: ['本篇文章实现了新建、保存、另存、打开、页面设置、退出功能\n\n不足的是新窗口和打印功能未实现\n\n但是近期我将暂停本项目的更新,假以时日,羽翼丰满,再更新\n\n欢迎关注我的动态,一起变得更强!\n']
2editText: ['本篇文章实现了新建、保存、另存、打开、页面设置、退出功能\n\n不足的是新窗口和打印功能未实现\n\n但是近期我将暂停本项目的更新,假以时日,羽翼丰满,再更新\n\n欢迎关注我的动态,一起变得更强!\n']
2readText: ['']
光标位置:行 7 列 17
"""
记事本功能设计
不足:
1.新窗口未完成,因为现在实现的话,会局限这里(功能不完全),所以要在最后实现
2.打印未实现,能力所限,只好忽略
3.在点击菜单栏后理应该可以与键盘交互,但未实现,因为Menu()没有鼠标焦点属性
"""
# 通配符 "*"
__all__ = ['Notepad_2']
# 导入内置模块
import tkinter.messagebox as tkmb
import tkinter.filedialog as tkfd
# 导入"记事本功能设计_1"模块
from 记事本项目.code.记事本功能设计_1 import Notepad_1
# 导入"记事本_页面设置功能设计_1"模块
from 记事本项目.code.记事本_页面设置功能设计_1 import PageSetup_1
class Notepad_2(Notepad_1):
""" 继承Notepad_1, 设计记事本功能 """
def __init__(self):
""" 重写父类的构造方法 """
# 调用父类的构造方法
super().__init__()
""" 开始对记事本功能进行设计 """
self.readText = '' # 读取编辑区文本数据
# 新建(N)
self.fileMenu.entryconfigure(0, command=self.newText)
""" 新窗口(W)要在最后完成,因为"新窗口"需要完整的功能 """
# self.fileMenu.entryconfigure(1, command=self.xxx)
# 打开(O)...
self.fileMenu.entryconfigure(2, command=self.openFile)
# 保存(S)
self.fileMenu.entryconfigure(3, command=self.saveFile)
# 另存为(A)...
self.fileMenu.entryconfigure(4, command=self.saveAsFile)
""" 页面设置(U)...需要单独一个继承类来完成 """
self.fileMenu.entryconfigure(6, command=self.pageSetup)
""" 打印(P)... 水平有限,功能未完成 """
# self.fileMenu.entryconfigure(7, command=self.xxx)
# 退出
self.fileMenu.entryconfigure(9, command=self.destroy)
# 捆绑按键按下编辑文本事件
self.bind('<KeyPress>', self.editText)
# 新建文本 键盘触发
self.bind('<Control-Key-n>', self.newText)
""" 新窗口未实现 """
# self.bind('Control-Shift-Key-N>', self.xxx)
# 打开文件(BUG) 键盘触发
self.bind('<Control-Key-o>', self.openFile)
# 保存文件 键盘触发
self.bind('<Control-Key-s>', self.saveFile)
# 文件另存为 键盘触发
self.bind('<Control-Shift-Key-S>', self.saveAsFile)
""" 打印未实现 """
# self.bind('Control-Key-p>', self.xxx)
# 页面设置
def pageSetup(self, event=None):
pageSetup_ui = PageSetup_1() # 实例化"页面设置"UI
# 文件另存为
def saveAsFile(self, event=None):
global openPath
# 文件保存类型
filetypes = [("文本文档", ".txt"), ("所有文件", ".*")]
# 保存文件对话框
savePath = tkfd.asksaveasfile(defaultextension=".txt", initialfile='*.txt', filetypes=filetypes)
# 确定保存
if savePath:
# 把文本编辑的数据写入文件
with open(savePath.name, 'w', encoding=savePath.encoding) as file:
file.write(self.text.get('1.0', 'end')[:-1:])
# 窗口标题前去掉'*'
self.title(self.title()[1::])
# 修改标题
self.title(f'{savePath.name.split("/")[-1]} - 记事本')
self.readText = self.text.get('1.0', 'end')[:-1:]
openPath = savePath
# 保存文件
def saveFile(self, event=None):
global openPath
# 判断文本是否编辑过
if self.title()[0] == '*':
self.bell() # 警告声
# 从程序打开进入的编辑
if not self.readText:
# 消息对话框选择是否保存
ifYes = tkmb.askyesnocancel('记事本', f'你想将更改保存到 无标题 吗?')
# 如果选择是
if ifYes:
# 文件另存为
self.saveAsFile()
# 打开文件后保存
else:
# 保存文本数据,写入文件
with open(openPath.name, 'w', encoding=openPath.encoding) as file:
file.write(self.text.get('1.0', 'end')[:-1:])
# 窗口标题前去掉'*'
self.title(self.title()[1::])
self.readText = self.text.get('1.0', 'end')[:-1:]
# 打开文件
def openFile(self, keyTrigger=None):
global openPath
ifYes = True
savePath = True
# 如果是键盘触发(必须)
if keyTrigger:
# 键盘Ctrl+O 触发,光标处会加入换行(不知道是否为BUG,求指教)
self.text.delete('1.0', 'end')
self.text.insert('1.0', self.textGet[:-1:])
# 判断文本是否编辑过
if self.title()[0] == '*':
self.bell() # 警告声
# 从程序打开进入的编辑
if not self.readText:
fileName = f'你想将更改保存到 {self.title().split(" ")[0][1::]} 吗?'
# 从文件打开进入的编辑
else:
fileName = f'你想将更改保存到\n{openPath.name}\n吗?'
# 在消息对话框选择是否保存当前编辑的文本
ifYes = tkmb.askyesnocancel('记事本', fileName)
# 确定
if ifYes:
# 判断保存的文件是否存在
if not self.readText:
# 文件另存为
self.saveAsFile()
else:
# 保存文本数据,写入文件
with open(openPath.name, 'w', encoding=openPath.encoding) as file:
file.write(self.text.get('1.0', 'end')[:-1:])
# 窗口标题前去掉'*'
self.title(self.title()[1::])
self.readText = self.text.get('1.0', 'end')[:-1:]
# 打开文件
if ifYes != None and savePath:
# 消息对话框打开文件
# must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable
filetypes = [('文本文档', '.txt'), ('所有文件', '.*')]
# 打开文件对话框
self.openPath = tkfd.askopenfile(filetypes=filetypes)
# 确定打开文件
if self.openPath:
openPath = self.openPath
# 窗口初始化
self.text.delete('1.0', 'end')
self.readText = ''
# 打开文件读取数据插入到文本域
with open(self.openPath.name, 'r', encoding=self.openPath.encoding) as file:
for i in file:
self.text.insert('end', i)
# 更新文本读取数据
self.readText += i
# 修改窗口标题
self.title(f'{self.openPath.name.split("/")[-1]} - 记事本')
self.event_generate('<Key>')
# 数据更新
# 新建文本
def newText(self, event=None):
ifYes = True
savePath = True
# 判断文本是否编辑过
if self.title()[0] == '*':
self.bell() # 警告声
# 从程序打开进入的编辑
if not self.readText:
fileName = f'你想将更改保存到 {self.title().split(" ")[0][1::]} 吗?'
# 从文件打开进入的编辑
else:
fileName = f'你想将更改保存到\n{openPath.name}\n吗?'
# 在消息对话框选择是否保存当前编辑的文本
ifYes = tkmb.askyesnocancel('记事本', fileName)
# 确定
if ifYes:
# 判断保存的文件是否存在
if not self.readText:
# 文件保存类型
filetypes = [("文本文档", ".txt"), ("所有文件", ".*")]
# 保存文件对话框
savePath = tkfd.asksaveasfile(defaultextension=".txt", initialfile='*.txt', filetypes=filetypes)
# 确定保存
if savePath:
# 把文本编辑的数据写入文件
with open(savePath.name, 'w', encoding=savePath.encoding) as file:
file.write(self.text.get('1.0', 'end')[:-1:])
else:
# 保存文本数据,写入文件
with open(openPath.name, 'w', encoding=openPath.encoding) as file:
file.write(self.text.get('1.0', 'end')[:-1:])
# 初始化窗口
if ifYes != None and savePath:
self.title('无标题 - 记事本')
self.readText = ''
self.text.delete('1.0', 'end')
self.event_generate('<Key>')
# 编辑Text文本
def editText(self, event=None):
print('1editText:', [self.text.get('1.0', 'end')])
data = self.text.get('1.0', 'end')
# 文本编辑时窗口标题前加入'*'
if data[:-1:] != self.readText and data != '\n' and self.title()[0] != '*':
self.title('*' + self.title())
# 编辑过文本未保存或与原文本相同时窗口标题前去掉'*'
elif data[:-1:] == self.readText or data == '\n':
if self.title()[0] == '*':
self.title(self.title()[1::])
# 如果是键盘Ctrl+O触发打开文件(必须)
self.textGet = self.text.get('1.0', 'end')
print('2editText:', [self.text.get('1.0', 'end')])
print('2readText:', [self.readText])
# 代码测试
if __name__ == '__main__':
ui = Notepad_2() # 实例化记事本UI
ui.mainloop() # 循环窗口运行
else:
print(f'导入【{__name__}】')
作者:周华
创作日期:2024/1/13