【Python小项目】简易记事本

缑勇锐
2023-12-01

【Python小项目】简易记事本

概要

  最近简单地学习了一下python,就想做个小项目来更进一步了解一下python的开发过程,然后就根据网上资料,制作了一个简易记事本(就搭了个框架)

实现的功能

  因为是小项目,对GUI的要求也不多,所以使用python自身提供的tkinter模块(另一个原因就是网上资料大多数也是用这个)
  因为是搭了个框架,所以实现的功能不多,如下:
  (1)"文件"选项:支持新建、保存、打开、退出功能
  (2)“帮助”选项:支持关于功能

代码

  由于大部分都是使用模块,所以就不分析了,直接贴代码。

# -*- coding: utf-8 -*-
# @Author  :   Zeepunt 
# @Blog    :   https://blog.csdn.net/h451884098
# @Desc    :   None
# @Time    :   2020/11/08 19:35:51

from tkinter import filedialog  # 引入文件对话框
from tkinter import messagebox  # 引入消息对话框

import tkinter as tk

class Applitons(object):
    def __init__(self):    
        self.editing = False
        self.run()

    def set_title_name(self, name=None, edit=False):
        if name == None:
            self.win.title("简易记事本")                # 设置窗口标题
        elif edit == False:
            self.win.title("简易记事本 - " + name)
        else: 
            self.win.title("简易记事本 - " + name + " * ")

    # 创建窗口
    def creat_windows(self):
        self.win = tk.Tk()              # 创建窗口
        self.set_title_name()        
        self.win_width = int(self.win.winfo_screenwidth() * 0.5)      # 获取当前屏幕的分辨率
        self.win_height = int(self.win.winfo_screenheight() * 0.5)
        self.win.geometry(str(self.win_width) + "x" + str(self.win_height) + "+200+300")   # 设置窗口大小:宽x高+距离屏幕左边宽+距离屏幕顶部高

        self.win.protocol("WM_DELETE_WINDOW", self.exit)    # 点击右上角"x"所触发的事件

    # 创建菜单栏
    def create_menu_bar(self):
        self.main_menu = tk.Menu(self.win)              # 创建一个主菜单

        file_menu = tk.Menu(self.main_menu, tearoff=False)             # 创建一个子菜单,该菜单不可被"撕下"
        edit_menu = tk.Menu(self.main_menu, tearoff=False)
        help_menu = tk.Menu(self.main_menu, tearoff=False)

        self.main_menu.add_cascade(label='文件(F)', menu=file_menu)         # 级联,将子菜单添加到主菜单中
        self.main_menu.add_cascade(label='编辑(E)', menu=edit_menu)
        self.main_menu.add_cascade(label='帮助(H)', menu=help_menu)

        # "文件"菜单项
        file_menu.add_command(label='新建', accelerator="ctrl+n", command=self.new_file)
        file_menu.add_command(label='打开', command=self.open_file)
        file_menu.add_command(label='保存', accelerator="ctrl+s", command=self.save_file)
        file_menu.add_command(label='关闭当前文件', command=self.close_cur_file)
        file_menu.add_separator()             # 添加分割线
        file_menu.add_command(label='退出', accelerator="ctrl+q", command=self.exit)
      
        # 对于快捷键的回调函数,都需要传入必要参数event
        self.win.bind("<Control-n>", self.new_file)    # ctrl+n 新建
        self.win.bind("<Control-s>", self.save_file)      # ctrl+s 保存
        self.win.bind("<Control-q>", self.exit)         # ctrl+q 退出

        # "编辑"菜单项

        # "帮助"菜单项
        help_menu.add_command(label='关于', command=self.about)

        self.win.config(menu=self.main_menu)                # 显示菜单     

    # 创建文本窗口
    def create_text_box(self):
        self.text = tk.Text(self.win)                   # 宽度单位为字符,高度单位为行
        
        self.scroll = tk.Scrollbar()                    # 加入滚动条
        self.scroll.pack(side=tk.RIGHT, fill=tk.Y)

        self.scroll.config(command=self.text.yview)         # 将滚动条和文本窗口关联起来
        self.text.config(yscrollcommand=self.scroll.set)

        self.text.bind("<Key>", self.edit)      # 绑定事件,Key表示所有键盘按键都会触发

        self.text.pack(fill=tk.BOTH, expand=tk.YES)     # 水平和竖直方向填充,扩展整个空白区      

    def new_file(self, event=None):
        try:
            self.close_cur_file()
            self.file_path = filedialog.asksaveasfilename(title="另存为", initialfile="新建文件.txt",
                                                        filetypes=[("文本文档", "*.txt")],
                                                        defaultextension=".txt")
            self.save_file()
        except Exception as e:
            raise ValueError()

    def open_file(self):
        try:
            self.close_cur_file()
            self.file_path = filedialog.askopenfilename()
            
            self.file_name = self.file_path.split('/')[-1]   # 从绝对路径中取文件名
            self.set_title_name(self.file_name)
            
            with open(self.file_path, 'r', encoding='utf-8') as f:
                content = f.readlines()
            
            if isinstance(content, str):
                self.text.insert(tk.INSERT, content)    # 往text插入内容
            else:
                for s in content:
                    self.text.insert(tk.INSERT, s)
        except Exception as e:
            raise ValueError()

    def save_file(self, event=None):
        try:
            with open(self.file_path, 'w', encoding='utf-8') as f:
                f.write(self.text.get('1.0', tk.END))      # 从第一行第一列到最后一个字符,将其写入文件中
            if self.editing:
                self.editing = False
                self.set_title_name(self.file_name)
        except Exception as e:
            raise ValueError() 

    def close_cur_file(self):
        self.ask_save()
        self.set_title_name()
        self.text.delete('1.0', tk.END)
        self.file_path = None
        self.file_name = None

    def ask_save(self):
        if self.editing:
            ret = messagebox.askyesno(title='提示',message='是否保存当前文件')
            if ret:
                self.save_file()
                self.editing = False

    def edit(self, event=None):
        self.editing = True
        self.set_title_name(self.file_name, True)

    def exit(self, event=None):
        self.ask_save()
        self.win.quit()
        
    def about(self):
        ret = messagebox.showinfo(title='关于',message='作者:Zeepunt')

    # 运行
    def run(self):
        try:
            self.creat_windows()
            self.create_menu_bar()
            self.create_text_box()  
            
            self.win.mainloop()   # 进入消息循环
        except Exception as e:
            print("run error: %s" % e)

if __name__ == "__main__":  
    win = Applitons()
 类似资料: