python pyside2 plain text edit(QPlainTextEdit) 作者:马育民 • 2025-09-13 20:15 • 阅读:10001 # 介绍 `QPlainTextEdit` 是 PySide2 中专为 **多行纯文本编辑** 设计的控件,继承自 `QAbstractScrollArea`,具备轻量渲染、高效编辑的特性,尤其适合处理代码、日志、配置文件等无格式文本。 ### 功能 仅支持纯文本(无富格式),专注于多行文本的输入、编辑与展示; ### 优点 1. **性能优化**:采用 `QPlainTextDocument` 存储文本,比支持富格式的 `QTextEdit` 更轻量,处理十万级行文本时卡顿感显著降低; 2. **滚动友好**:内置垂直 / 水平滚动条,文本超出可视区域时自动适配; 3. **编辑便捷**:支持快捷键(复制 / 粘贴 / 撤销)、文本选中、行定位等基础编辑能力; ### 适用场景 代码编辑器、日志查看器、配置文件编辑、多行文本输入(如备注、反馈)。 # 基础用法 ### 1. 控件创建与基础配置 ``` from PySide2.QtWidgets import QApplication, QPlainTextEdit, QWidget, QVBoxLayout import sys app = QApplication(sys.argv) window = QWidget() window.setWindowTitle("QPlainTextEdit 基础示例") layout = QVBoxLayout(window) \# 1. 初始化 QPlainTextEdit(默认空文本,支持多行) plain\_edit = QPlainTextEdit() \# 2. 基础配置 plain\_edit.setPlaceholderText("请输入多行纯文本(如日志、代码)...") # 输入提示 plain\_edit.setLineWrapMode(QPlainTextEdit.WidgetWidth) # 自动换行(按控件宽度折行) \# plain\_edit.setLineWrapMode(QPlainTextEdit.NoWrap) # 禁止换行(适合代码编辑,需横向滚动) \# 3. 设置初始文本(支持 \n 换行) initial\_text = """# 日志记录 \[2025-10-01 09:00:00] 程序启动成功 \[2025-10-01 09:01:30] 加载配置文件 config.ini \[2025-10-01 09:02:15] 连接数据库成功 \[2025-10-01 09:03:40] 接收用户请求:/api/getData """ plain\_edit.setPlainText(initial\_text) layout.addWidget(plain\_edit) window.show() sys.exit(app.exec\_()) ``` ### 2. 核心文本操作方法 | 方法 | 功能描述 | 示例代码 | | -------------------------- | -------------------------------------------- | ---------------------------------------- | | `setPlainText(str)` | 设置控件的纯文本内容(覆盖原有内容) | `edit.setPlainText("新文本\n第二行")` | | `toPlainText()` | 获取当前所有文本内容(含换行符 `\n`) | `content = edit.toPlainText()` | | `appendPlainText(str)` | 在文本末尾追加新文本(自动换行) | `edit.appendPlainText("[10:00] 新日志")` | | `clear()` | 清空所有文本内容 | `edit.clear()` | | `selectAll()` | 全选当前文本 | `edit.selectAll()` | | `cut()`/`copy()`/`paste()` | 剪切 / 复制 / 粘贴文本(需绑定快捷键或按钮) | `edit.copy()`(复制选中内容) | ### 3. 文本选中与光标控制 `QPlainTextEdit` 通过 `textCursor()` 获取光标对象(`QTextCursor`),实现精准的文本选中与光标定位,适合需要 “局部编辑” 的场景(如代码高亮、文本替换): ``` \# 1. 选中指定范围的文本(参数:起始位置,选中长度) plain\_edit.setPlainText("Hello PySide2\nThis is QPlainTextEdit") QTextCursor cursor = plain\_edit.textCursor() cursor.setPosition(6) # 光标移到索引 6("PySide2" 开头) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, 7) # 向右选中 7 个字符("PySide2") plain\_edit.setTextCursor(cursor) # 应用选中状态 \# 2. 光标定位到文本末尾(常用于追加文本后自动滚动到底部) def scroll\_to\_bottom(): cursor = plain\_edit.textCursor() cursor.movePosition(QTextCursor.End) # 光标移到末尾 plain\_edit.setTextCursor(cursor) plain\_edit.ensureCursorVisible() # 确保光标所在行可见(自动滚动) \# 3. 获取选中的文本 def get\_selected\_text(): if plain\_edit.textCursor().hasSelection(): print("选中的文本:", plain\_edit.textCursor().selectedText()) else: print("未选中任何文本") \# 绑定按钮触发选中与获取操作(示例) from PySide2.QtWidgets import QPushButton select\_btn = QPushButton("选中 PySide2") select\_btn.clicked.connect(lambda: cursor\_operation()) get\_btn = QPushButton("获取选中文本") get\_btn.clicked.connect(get\_selected\_text) layout.addWidget(select\_btn) layout.addWidget(get\_btn) ``` # 进阶功能 ### 文本搜索与替换 结合 `QTextCursor` 实现 “查找下一个”“替换” 功能,适合日志检索、代码修改场景: ``` from PySide2.QtWidgets import QHBoxLayout, QLineEdit, QPushButton, QMessageBox class SearchReplaceWidget(QWidget): def \_\_init\_\_(self, plain\_edit): super().\_\_init\_\_() self.plain\_edit = plain\_edit self.current\_position = 0 # 当前搜索起始位置 self.init\_ui() def init\_ui(self): layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) \# 搜索输入框 self.search\_edit = QLineEdit() self.search\_edit.setPlaceholderText("输入搜索文本...") \# 替换输入框 self.replace\_edit = QLineEdit() self.replace\_edit.setPlaceholderText("输入替换文本...") \# 按钮 self.find\_btn = QPushButton("查找下一个") self.replace\_btn = QPushButton("替换") \# 绑定事件 self.find\_btn.clicked.connect(self.find\_next) self.replace\_btn.clicked.connect(self.replace\_current) self.search\_edit.returnPressed.connect(self.find\_next) # 回车触发查找 layout.addWidget(self.search\_edit) layout.addWidget(self.replace\_edit) layout.addWidget(self.find\_btn) layout.addWidget(self.replace\_btn) \# 查找下一个匹配项 def find\_next(self): search\_text = self.search\_edit.text().strip() if not search\_text: QMessageBox.warning(self, "提示", "请输入搜索文本!") return \# 获取全文 full\_text = self.plain\_edit.toPlainText() \# 从当前位置开始搜索 index = full\_text.indexOf(search\_text, self.current\_position) if index != -1: \# 选中找到的文本 cursor = self.plain\_edit.textCursor() cursor.setPosition(index) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, len(search\_text)) self.plain\_edit.setTextCursor(cursor) self.plain\_edit.ensureCursorVisible() # 滚动到可视区域 \# 更新下一次搜索起始位置 self.current\_position = index + len(search\_text) \# 若已到文本末尾,重置位置 if self.current\_position >= len(full\_text): self.current\_position = 0 else: QMessageBox.information(self, "提示", "已找到最后一个匹配项!") self.current\_position = 0 \# 替换当前选中的匹配项 def replace\_current(self): search\_text = self.search\_edit.text().strip() replace\_text = self.replace\_edit.text() if not search\_text: QMessageBox.warning(self, "提示", "请输入搜索文本!") return cursor = self.plain\_edit.textCursor() if cursor.hasSelection() and cursor.selectedText() == search\_text: cursor.insertText(replace\_text) # 替换选中文本 self.current\_position = cursor.position() # 更新搜索位置 self.find\_next() # 自动查找下一个 else: \# 未选中或选中内容不匹配,先查找 self.find\_next() \# 应用搜索替换功能 app = QApplication(sys.argv) window = QWidget() window.setWindowTitle("QPlainTextEdit 搜索替换") layout = QVBoxLayout(window) plain\_edit = QPlainTextEdit() plain\_edit.setPlainText("Python 是一门优雅的语言\nPython 适合数据分析\nPython 也适合 GUI 开发") search\_replace\_widget = SearchReplaceWidget(plain\_edit) layout.addWidget(search\_replace\_widget) layout.addWidget(plain\_edit) window.show() sys.exit(app.exec\_()) ``` ### 只读模式 设置 `setReadOnly(True)` 后,文本仅可查看、复制,无法修改,适合展示日志、报告等静态内容: ``` plain\_edit = QPlainTextEdit() plain\_edit.setPlainText("\[日志开始]\n2025-10-01 09:00: 系统启动\n2025-10-01 09:05: 连接成功") plain\_edit.setReadOnly(True) # 启用只读模式 \# 可选:设置文本颜色(灰色,增强只读视觉效果) plain\_edit.setStyleSheet("color: #666666;") ``` ### 样式定制(美化外观) 通过 `setStyleSheet` 定制控件样式,支持背景色、边框、字体等,适配整体界面风格: ``` plain\_edit.setStyleSheet(""" QPlainTextEdit { background-color: #f8f9fa; /\* 背景色(浅灰) \*/ border: 1px solid #dee2e6; /\* 边框(淡蓝灰) \*/ border-radius: 6px; /\* 圆角 \*/ padding: 8px; /\* 内边距(避免文本贴边) \*/ font-family: "Consolas", "Microsoft YaHei"; /\* 字体(适合代码/日志) \*/ font-size: 14px; /\* 字体大小 \*/ color: #212529; /\* 文本颜色(深灰) \*/ } QPlainTextEdit:focus { border-color: #80bdff; /\* 获焦时边框色(淡蓝) \*/ outline: none; /\* 清除默认获焦外框 \*/ } QPlainTextEdit:read-only { background-color: #e9ecef; /\* 只读时背景色(更浅的灰) \*/ } """) ``` 原文出处:http://malaoshi.top/show_1GW1r61r8dNU.html