python pyside2 plain text edit(QPlainTextEdit)

介绍

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 PySide2nThis 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;  /* 只读时背景色(更浅的灰) */

}

""")

原文出处:/show_1GW1r61r8dNU.html