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