教你30分钟使用Python制作自己的记事本

Written by

in

文章目录
  • 常见错误:直接写window.show()但窗口不显示? 正确逻辑:程序运行流程图 代码详解(逐行解释) import sys # 必须!用于接收系统参数(比如文件路径) from PyQt6.QtWidgets import QApplication, QMainWindow # 从PyQt库导入两个核心组件 # 1️⃣ 创建应用对象(灵魂!所有PyQt程序必须有) app = QApplication(sys.argv) # sys.argv = 系统传递的命令行参数(比如打开的文件名) # 2️⃣ 创建主窗口(你的「画布」) window = QMainWindow() # 100% 会用到的窗口类型 window.setWindowTitle(“我的迷你记事本”) # 设置标题(为什么叫”窗口”?因为它是所有UI的容器!) window.resize(500, 400) # 设置大小(宽500px, 高400px) # 3️⃣ 显示窗口(关键!) window.show() # ✨ 为什么必须写?因为窗口默认是「隐形」的! # ❌ 如果不写这行,程序会直接结束,你永远看不到窗口! # 4️⃣ 进入事件循环(让程序「活」起来) sys.exit(app.exec()) # ✨ 为什么叫「事件循环」?因为程序会一直监听用户操作(点击、输入等) 思考题: 如果我删掉 sys.exit(app.exec()) 会怎样? 答案:程序会立刻结束!你只能看到一闪而过的窗口(就像打开一个网页立刻关闭)。
  • 常见错误:用QLineEdit(单行输入框)做记事本 → 无法输入多行文字! 正确选择:QTextEdit= 专为多行文本设计的编辑器 代码详解(添加编辑器): from PyQt6.QtWidgets import QApplication, QMainWindow, QTextEdit # 新增导入 app = QApplication(sys.argv) window = QMainWindow() window.setWindowTitle(“我的迷你记事本”) window.resize(700, 500) # 宽高调大一点(记事本需要更多空间) # ✨ 关键步骤:把编辑器设置为窗口的「中央内容」 editor = QTextEdit() # 创建编辑器对象 window.setCentralWidget(editor) # 设置为窗口的主区域 # ✨ 为什么叫「中央」?因为窗口可以有顶部菜单、底部状态栏,编辑器占中间大块 思考题: 如果我把 window.setCentralWidget(editor) 写成 window.setWidget(editor) 会怎样? 答案:报错!setCentralWidget 是 QMainWindow 的专属方法(PyQt 设计的规范)。
  • 常见错误:直接写menubar = menuBar()→ 无菜单! 正确逻辑:菜单 = 1个主菜单 + 多个子菜单项 代码详解(分步构建菜单): # 1️⃣ 创建菜单栏(必须先有窗口才有菜单栏) menubar = window.menuBar() # 获取窗口的菜单栏对象 # 2️⃣ 添加「文件」主菜单(为什么叫「主菜单」?因为它在最左边) file_menu = menubar.addMenu(“文件”) # 创建菜单项 # 3️⃣ 在「文件」里添加子菜单(每个子菜单是用户点击的按钮) open_action = file_menu.addAction(“打开文件”) # 添加「打开」按钮 save_action = file_menu.addAction(“保存文件”) # 添加「保存」按钮 # 4️⃣ 设置快捷键(为什么需要?因为用户习惯Ctrl+S!) save_action.setShortcut(“Ctrl+S”) # 40% 用户会用快捷键 思考题: 为什么「打开」和「保存」要用 addAction 而不是 addButton? 答案:QAction 是 PyQt 的统一事件处理单元(不是按钮!),它能绑定到菜单/按钮/工具栏。
  • 常见错误:忘记with open→ 文件没关闭 → 内存泄漏! 正确逻辑:用户点击 → 弹出文件选择框 → 读取文件 → 显示到编辑器 代码详解(带思考注释): def open_file(self): # ✨ 为什么用 QFileDialog.getOpenFileName?因为这是PyQt的标准文件选择器 path, _ = QFileDialog.getOpenFileName( self, # 父窗口(确保弹窗在记事本内部) “打开文件”, # 窗口标题 “”, # 默认打开路径(留空表示当前目录) “Text Files (*.txt);;All Files (*)” # 文件过滤器(显示.txt和所有文件) ) # ✨ 为什么需要检查 path?因为用户可能点了「取消」! if path: # ✨ 为什么用 ‘r’ 和 utf-8?因为读取文本文件,且支持中文 with open(path, ‘r’, encoding=’utf-8′) as f: self.editor.setText(f.read()) # 将文件内容放入编辑器 # ✨ 为什么更新状态栏?让用户知道发生了什么 self.statusBar().showMessage(f”已打开: {path}”) 思考题: 如果用户打开一个 .jpg 文件会怎样? 答案:程序会崩溃!因为 f.read() 读的是二进制,不是文本。这就是为什么需要文件过滤器("Text Files (*.txt)")。
  • 常见错误:用self.editor.text()→ 会包含HTML标签! 正确逻辑:实时监听文字变化 → 计算纯文本字数 代码详解(关键在textChanged信号): # 1️⃣ 初始化状态栏(在 initUI 里) self.statusBar().showMessage(“准备就绪”) # 初始状态 # 2️⃣ 监听文字变化(核心!) self.editor.textChanged.connect(self.update_status) # 当文字变化时,自动调用 update_status # 3️⃣ 实现统计函数 def update_status(self): text = self.editor.toPlainText() # ✨ 为什么用 toPlainText?因为这是纯文本! char_count = len(text) # 字符数(含空格) line_count = len(text.split(‘n’)) # 行数(按换行符分割) # 更新状态栏(为什么用 f-string?因为可读性高!) self.statusBar().showMessage(f”字数: {char_count} | 行数: {line_count}”) 思考题: 为什么 text.split('n') 能算行数?如果用户用的是 rn(Windows换行符)会怎样? 答案:split('n') 会把 rn 当成两个字符,导致行数多1。正确做法:用 text.splitlines()(PyQt内置方法,自动处理换行符)。
  • 常见错误:把所有代码写在全局(导致变量混乱!) 正确逻辑:用类封装所有功能→ 代码清晰 + 方便绑定槽函数 为什么这样写? class SimplePad(QMainWindow): # 继承自QMainWindow(让记事本拥有窗口能力) def __init__(self): super().__init__() # 初始化父类(必须!) self.initUI() # 自己写的初始化方法 def initUI(self): # 这里放所有界面初始化代码(窗口、编辑器、菜单等) # ✨ 为什么不用全局变量?因为:1. 代码可读性高 2. 便于多人协作 3. 避免变量覆盖 思考题: 如果我删掉 super().__init__() 会怎样? 答案:窗口会报错!因为 QMainWindow 的初始化逻辑没执行(PyQt要求必须调用父类构造函数)。
  • import sys from PyQt6.QtWidgets import QApplication, QMainWindow, QTextEdit, QFileDialog, QFontDialog, QMenuBar, QStatusBar class SimplePad(QMainWindow): def __init__(self): super().__init__() # 1️⃣ 必须初始化父类 self.initUI() # 2️⃣ 初始化界面 def initUI(self): # 🔧 1. 设置窗口基础属性 self.setWindowTitle(“SimplePad – 我的第一个记事本”) self.resize(800, 600) # 更大的窗口(方便看字数) # 📝 2. 创建文本编辑器(核心!) self.editor = QTextEdit() self.setCentralWidget(self.editor) # 设置为窗口中央内容 # 📋 3. 创建菜单栏(分步骤构建) menubar = self.menuBar() # 获取菜单栏 # 文件菜单 file_menu = menubar.addMenu(“文件”) file_menu.addAction(“新建”).triggered.connect(self.editor.clear) # 新建 → 清空 file_menu.addAction(“打开”).triggered.connect(self.open_file) # 打开 → 绑定函数 save_action = file_menu.addAction(“保存”) save_action.setShortcut(“Ctrl+S”) # 快捷键 save_action.triggered.connect(self.save_file) # 保存 → 绑定函数 # 格式菜单 format_menu = menubar.addMenu(“格式”) format_menu.addAction(“字体设置”).triggered.connect(self.change_font) # 📊 4. 状态栏(字数统计) self.statusBar().showMessage(“准备就绪”) self.editor.textChanged.connect(self.update_status) # 关键!监听文字变化 # ⚙️ 5. 打开文件(带错误处理) def open_file(self): path, _ = QFileDialog.getOpenFileName( self, “打开文件”, “”, “Text Files (*.txt);;All Files (*)” ) if path: # ✅ 检查用户是否选择了文件 with open(path, ‘r’, encoding=’utf-8′) as f: self.editor.setText(f.read()) self.statusBar().showMessage(f”已打开: {path}”) # 📦 6. 保存文件(带用户友好提示) def save_file(self): path, _ = QFileDialog.getSaveFileName( self, “保存文件”, “”, “Text Files (*.txt)” ) if path: content = self.editor.toPlainText() # ✨ 纯文本! with open(path, ‘w’, encoding=’utf-8′) as f: f.write(content) self.statusBar().showMessage(f”已保存: {path}”) # 🎨 7. 字体设置(用标准对话框) def change_font(self): font, ok = QFontDialog.getFont() if ok: self.editor.setFont(font) # 📊 8. 字数统计(实时更新!) def update_status(self): text = self.editor.toPlainText() char_count = len(text) line_count = len(text.splitlines()) # ✨ 正确处理换行符! self.statusBar().showMessage(f”字数: {char_count} | 行数: {line_count}”) # 🚀 启动程序 if __name__ == “__main__”: app = QApplication(sys.argv) window = SimplePad() window.show() sys.exit(app.exec()) 以上就是教你30分钟使用Python制作自己的记事本的详细内容,更多关于Python记事本的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: Python+PyQt手搓一个简单的记事本 Python用tkinter实现自定义记事本的方法详解 python实现记事本功能 教你如何使用Python Tkinter库制作记事本 python 实现简易的记事本 Python使用字典实现的简单记事本功能示例
  • 目录
    • 第一步:为什么我们需要「基础窗口」?(新手必懂!)
    • 第二步:为什么需要QTextEdit?(小白必看!)
    • 第三步:菜单栏怎么设计?(不是复制粘贴!)
    • 第四步:实现「打开文件」功能(关键!)
    • 第五步:实现「字数统计」(小白最爱的功能!)
    • 第六步:为什么需要「类结构」?(小白的终极困惑)
    • 最终代码(完整版,带详细注释)

    常见错误:直接写window.show()但窗口不显示?

    正确逻辑:程序运行流程图

    代码详解(逐行解释)

    import sys  # 必须!用于接收系统参数(比如文件路径)
    from PyQt6.QtWidgets import QApplication, QMainWindow  # 从PyQt库导入两个核心组件
    
    # 1️⃣ 创建应用对象(灵魂!所有PyQt程序必须有)
    app = QApplication(sys.argv)  # sys.argv = 系统传递的命令行参数(比如打开的文件名)
    
    # 2️⃣ 创建主窗口(你的「画布」)
    window = QMainWindow()  # 100% 会用到的窗口类型
    window.setWindowTitle("我的迷你记事本")  # 设置标题(为什么叫"窗口"?因为它是所有UI的容器!)
    window.resize(500, 400)  # 设置大小(宽500px, 高400px)
    
    # 3️⃣ 显示窗口(关键!)
    window.show()  # ✨ 为什么必须写?因为窗口默认是「隐形」的!
    # ❌ 如果不写这行,程序会直接结束,你永远看不到窗口!
    
    # 4️⃣ 进入事件循环(让程序「活」起来)
    sys.exit(app.exec())  # ✨ 为什么叫「事件循环」?因为程序会一直监听用户操作(点击、输入等)
    

    思考题:

    如果我删掉 sys.exit(app.exec()) 会怎样?

    答案:程序会立刻结束!你只能看到一闪而过的窗口(就像打开一个网页立刻关闭)。

    常见错误:用QLineEdit(单行输入框)做记事本 → 无法输入多行文字!

    正确选择:QTextEdit= 专为多行文本设计的编辑器

    代码详解(添加编辑器):

    from PyQt6.QtWidgets import QApplication, QMainWindow, QTextEdit  # 新增导入
    
    app = QApplication(sys.argv)
    window = QMainWindow()
    window.setWindowTitle("我的迷你记事本")
    window.resize(700, 500)  # 宽高调大一点(记事本需要更多空间)
    
    # ✨ 关键步骤:把编辑器设置为窗口的「中央内容」
    editor = QTextEdit()  # 创建编辑器对象
    window.setCentralWidget(editor)  # 设置为窗口的主区域
    
    # ✨ 为什么叫「中央」?因为窗口可以有顶部菜单、底部状态栏,编辑器占中间大块
    

    思考题:

    如果我把 window.setCentralWidget(editor) 写成 window.setWidget(editor) 会怎样?

    答案:报错!setCentralWidget 是 QMainWindow 的专属方法(PyQt 设计的规范)。

    常见错误:直接写menubar = menuBar()→ 无菜单!

    正确逻辑:菜单 = 1个主菜单 + 多个子菜单项

    代码详解(分步构建菜单):

    # 1️⃣ 创建菜单栏(必须先有窗口才有菜单栏)
    menubar = window.menuBar()  # 获取窗口的菜单栏对象
    
    # 2️⃣ 添加「文件」主菜单(为什么叫「主菜单」?因为它在最左边)
    file_menu = menubar.addMenu("文件")  # 创建菜单项
    
    # 3️⃣ 在「文件」里添加子菜单(每个子菜单是用户点击的按钮)
    open_action = file_menu.addAction("打开文件")  # 添加「打开」按钮
    save_action = file_menu.addAction("保存文件")  # 添加「保存」按钮
    
    # 4️⃣ 设置快捷键(为什么需要?因为用户习惯Ctrl+S!)
    save_action.setShortcut("Ctrl+S")  # 40% 用户会用快捷键
    

    思考题:

    为什么「打开」和「保存」要用 addAction 而不是 addButton

    答案QAction 是 PyQt 的统一事件处理单元(不是按钮!),它能绑定到菜单/按钮/工具栏。

    常见错误:忘记with open→ 文件没关闭 → 内存泄漏!

    正确逻辑:用户点击 → 弹出文件选择框 → 读取文件 → 显示到编辑器

    代码详解(带思考注释):

    def open_file(self):
        # ✨ 为什么用 QFileDialog.getOpenFileName?因为这是PyQt的标准文件选择器
        path, _ = QFileDialog.getOpenFileName(
            self,  # 父窗口(确保弹窗在记事本内部)
            "打开文件",  # 窗口标题
            "",  # 默认打开路径(留空表示当前目录)
            "Text Files (*.txt);;All Files (*)"  # 文件过滤器(显示.txt和所有文件)
        )
        
        # ✨ 为什么需要检查 path?因为用户可能点了「取消」!
        if path:
            # ✨ 为什么用 'r' 和 utf-8?因为读取文本文件,且支持中文
            with open(path, 'r', encoding='utf-8') as f:
                self.editor.setText(f.read())  # 将文件内容放入编辑器
            
            # ✨ 为什么更新状态栏?让用户知道发生了什么
            self.statusBar().showMessage(f"已打开: {path}")
    

    思考题:

    如果用户打开一个 .jpg 文件会怎样?

    答案:程序会崩溃!因为 f.read() 读的是二进制,不是文本。这就是为什么需要文件过滤器"Text Files (*.txt)")。

    常见错误:用self.editor.text()→ 会包含HTML标签!

    正确逻辑:实时监听文字变化 → 计算纯文本字数

    代码详解(关键在textChanged信号):

    # 1️⃣ 初始化状态栏(在 initUI 里)
    self.statusBar().showMessage("准备就绪")  # 初始状态
    
    # 2️⃣ 监听文字变化(核心!)
    self.editor.textChanged.connect(self.update_status)  # 当文字变化时,自动调用 update_status
    
    # 3️⃣ 实现统计函数
    def update_status(self):
        text = self.editor.toPlainText()  # ✨ 为什么用 toPlainText?因为这是纯文本!
        char_count = len(text)  # 字符数(含空格)
        line_count = len(text.split('n'))  # 行数(按换行符分割)
        
        # 更新状态栏(为什么用 f-string?因为可读性高!)
        self.statusBar().showMessage(f"字数: {char_count} | 行数: {line_count}")
    

    思考题:

    为什么 text.split('n') 能算行数?如果用户用的是 rn(Windows换行符)会怎样?

    答案split('n') 会把 rn 当成两个字符,导致行数多1。正确做法:用 text.splitlines()(PyQt内置方法,自动处理换行符)。

    常见错误:把所有代码写在全局(导致变量混乱!)

    正确逻辑:用类封装所有功能→ 代码清晰 + 方便绑定槽函数

    为什么这样写?

    class SimplePad(QMainWindow):  # 继承自QMainWindow(让记事本拥有窗口能力)
        def __init__(self):
            super().__init__()  # 初始化父类(必须!)
            self.initUI()  # 自己写的初始化方法
    
        def initUI(self):
            # 这里放所有界面初始化代码(窗口、编辑器、菜单等)
            # ✨ 为什么不用全局变量?因为:1. 代码可读性高 2. 便于多人协作 3. 避免变量覆盖
    

    思考题:

    如果我删掉 super().__init__() 会怎样?

    答案:窗口会报错!因为 QMainWindow 的初始化逻辑没执行(PyQt要求必须调用父类构造函数)。

    import sys
    from PyQt6.QtWidgets import QApplication, QMainWindow, QTextEdit, QFileDialog, QFontDialog, QMenuBar, QStatusBar
    
    class SimplePad(QMainWindow):
        def __init__(self):
            super().__init__()  # 1️⃣ 必须初始化父类
            self.initUI()  # 2️⃣ 初始化界面
    
        def initUI(self):
            # 🔧 1. 设置窗口基础属性
            self.setWindowTitle("SimplePad - 我的第一个记事本")
            self.resize(800, 600)  # 更大的窗口(方便看字数)
    
            # 📝 2. 创建文本编辑器(核心!)
            self.editor = QTextEdit()
            self.setCentralWidget(self.editor)  # 设置为窗口中央内容
    
            # 📋 3. 创建菜单栏(分步骤构建)
            menubar = self.menuBar()  # 获取菜单栏
            
            # 文件菜单
            file_menu = menubar.addMenu("文件")
            file_menu.addAction("新建").triggered.connect(self.editor.clear)  # 新建 → 清空
            file_menu.addAction("打开").triggered.connect(self.open_file)  # 打开 → 绑定函数
            save_action = file_menu.addAction("保存")
            save_action.setShortcut("Ctrl+S")  # 快捷键
            save_action.triggered.connect(self.save_file)  # 保存 → 绑定函数
    
            # 格式菜单
            format_menu = menubar.addMenu("格式")
            format_menu.addAction("字体设置").triggered.connect(self.change_font)
    
            # 📊 4. 状态栏(字数统计)
            self.statusBar().showMessage("准备就绪")
            self.editor.textChanged.connect(self.update_status)  # 关键!监听文字变化
    
        # ⚙️ 5. 打开文件(带错误处理)
        def open_file(self):
            path, _ = QFileDialog.getOpenFileName(
                self, "打开文件", "", "Text Files (*.txt);;All Files (*)"
            )
            if path:  # ✅ 检查用户是否选择了文件
                with open(path, 'r', encoding='utf-8') as f:
                    self.editor.setText(f.read())
                self.statusBar().showMessage(f"已打开: {path}")
    
        # 📦 6. 保存文件(带用户友好提示)
        def save_file(self):
            path, _ = QFileDialog.getSaveFileName(
                self, "保存文件", "", "Text Files (*.txt)"
            )
            if path:
                content = self.editor.toPlainText()  # ✨ 纯文本!
                with open(path, 'w', encoding='utf-8') as f:
                    f.write(content)
                self.statusBar().showMessage(f"已保存: {path}")
    
        # 🎨 7. 字体设置(用标准对话框)
        def change_font(self):
            font, ok = QFontDialog.getFont()
            if ok:
                self.editor.setFont(font)
    
        # 📊 8. 字数统计(实时更新!)
        def update_status(self):
            text = self.editor.toPlainText()
            char_count = len(text)
            line_count = len(text.splitlines())  # ✨ 正确处理换行符!
            self.statusBar().showMessage(f"字数: {char_count} | 行数: {line_count}")
    
    # 🚀 启动程序
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = SimplePad()
        window.show()
        sys.exit(app.exec())
    

    以上就是教你30分钟使用Python制作自己的记事本的详细内容,更多关于Python记事本的资料请关注风君子博客其它相关文章!

    您可能感兴趣的文章:

    • Python+PyQt手搓一个简单的记事本
    • Python用tkinter实现自定义记事本的方法详解
    • python实现记事本功能
    • 教你如何使用Python Tkinter库制作记事本
    • python 实现简易的记事本
    • Python使用字典实现的简单记事本功能示例

    站内搜索