文字输入类控件用于接收用户文本 / 数值输入,是表单、设置界面的核心组件。
1. QLineEdit(单行文本框)
核心作用:单行文本输入(如用户名、密码、搜索框)。
关键特性:
- 密码模式:setEchoMode(QLineEdit.Password);
- 输入验证:通过 QValidator 限制输入格式(整数、浮点数、正则);
- 占位符提示:setPlaceholderText("请输入用户名");
- 信号:textChanged(str)(实时变化)、editingFinished()(输入完成)。
输入验证示例:
import sys from PySide6.QtWidgets import QLineEdit, QApplication app = QApplication(sys.argv) line_edit = QLineEdit() # 仅允许输入数字 line_edit.setPlaceholderText("请输入数字") # 设置占位符 def on_text_changed(text): if not text.isdigit(): print("输入错误,请修改") line_edit.setStyleSheet("color: red") else: line_edit.setStyleSheet("color: black") line_edit.textChanged.connect(on_text_changed) line_edit.show() app.exec()2. QPlainTextEdit(纯文本框)
QPlainTextEdit 是 PySide6 中用于编辑和显示纯文本的控件,专为处理大文本文件优化(相比 QTextEdit 更轻量,无富文本渲染开销),支持行号、语法高亮、撤销 / 重做、文本选择、滚动等核心功能,是编写日志查看器、代码编辑器、纯文本编辑器的首选控件。
核心特性
- 轻量级纯文本处理:仅处理纯文本,无富文本(如字体 / 颜色 / 图片)渲染,性能优于 QTextEdit;
- 行级操作:便捷的行增删、行内容获取 / 修改;
- 编辑功能:默认支持撤销、重做、复制、粘贴、剪切;
- 滚动与视图:支持自动滚动、光标定位、可见区域控制;
- 信号与槽:文本变化、光标移动、选择变化等信号,便于交互逻辑实现;
- 自定义扩展:可结合 QSyntaxHighlighter 实现语法高亮,结合 QAbstractScrollArea 自定义滚动条 / 行号。
基本使用
1. 基础初始化与布局
import sys from PySide6.QtWidgets import (QApplication, QMainWindow, QPlainTextEdit, QVBoxLayout, QWidget) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("QPlainTextEdit 示例") self.resize(800, 600) # 1. 创建 QPlainTextEdit 实例 self.text_edit = QPlainTextEdit() # 2. 基础配置 self.text_edit.setPlaceholderText("请输入纯文本内容...") # 占位提示 self.text_edit.setReadOnly(False) # 是否只读(True 则无法编辑) self.text_edit.setLineWrapMode(QPlainTextEdit.NoWrap) # NoWrap:不自动换行(默认) # QPlainTextEdit.WidgetWidth:按控件宽度自动换行 # 3. 设置中心部件 central_widget = QWidget() layout = QVBoxLayout(central_widget) layout.addWidget(self.text_edit) self.setCentralWidget(central_widget) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())2. 文本操作核心方法
| 方法 | 功能 | 示例 |
|---|---|---|
setPlainText(text) | 设置全部文本(覆盖原有内容) | self.text_edit.setPlainText("Hello PySide6!") |
toPlainText() | 获取全部文本(返回字符串) | text = self.text_edit.toPlainText() |
insertPlainText(text) | 在光标位置插入文本(不覆盖) | self.text_edit.insertPlainText("插入的内容") |
appendPlainText(text) | 在末尾追加文本(自动换行) | self.text_edit.appendPlainText("新行内容") |
clear() | 清空所有文本 | self.text_edit.clear() |
undo()/redo() | 撤销 / 重做操作 | self.text_edit.undo() |
copy()/cut()/paste() | 复制 / 剪切 / 粘贴 | self.text_edit.copy() |
行级操作(高频需求)
import sys from PySide6.QtGui import QTextCursor from PySide6.QtWidgets import (QApplication, QMainWindow, QPlainTextEdit, QVBoxLayout, QWidget) class MainWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("QPlainTextEdit 示例") self.resize(800, 600) # 1. 创建 QPlainTextEdit 实例 self.text_edit = QPlainTextEdit() # 2. 基础配置 self.text_edit.setPlainText("line0\n" "line1\n" "line2\n" "line3\n" "line4\n" "line5\n" "line6\n") self.text_edit.setReadOnly(False) # 是否只读(True 则无法编辑) self.text_edit.setLineWrapMode(QPlainTextEdit.NoWrap) # NoWrap:不自动换行(默认) # QPlainTextEdit.WidgetWidth:按控件宽度自动换行 # 获取当前光标所在行号(从 0 开始) # current_line = self.text_edit.textCursor().blockNumber() # print(current_line) # 3. 设置中心部件 central_widget = QWidget() layout = QVBoxLayout(central_widget) layout.addWidget(self.text_edit) self.setCentralWidget(central_widget) # 获取指定行内容(行号从 0 开始) def get_line_content(self, line_num): block = self.text_edit.document().findBlockByNumber(line_num) return block.text() if block.isValid() else "" # 修改指定行内容 def set_line_content(self, line_num, new_text): cursor = self.text_edit.textCursor() block = self.text_edit.document().findBlockByNumber(line_num) if block.isValid(): cursor.setPosition(block.position()) # 定位到行首 cursor.select(QTextCursor.SelectionType.BlockUnderCursor) # 选中整行 cursor.insertText(new_text) # 替换内容 # 删除指定行 def delete_line(self, line_num): cursor = self.text_edit.textCursor() block = self.text_edit.document().findBlockByNumber(line_num) if block.isValid(): cursor.setPosition(block.position()) cursor.select(QTextCursor.SelectionType.BlockUnderCursor) cursor.removeSelectedText() # 删除选中内容 # 移除多余的换行符(可选) # cursor.deleteChar() if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() print(f"第一行内容:", window.get_line_content(1)) # 获取第二行内容 window.set_line_content(1, "\n新内容1") # 修改第二行内容 print(f"第一行内容:", window.get_line_content(1)) # 获取第二行内容 window.delete_line(3) window.show() sys.exit(app.exec())光标与选择控制
QPlainTextEdit 的光标操作依赖QTextCursor,可实现精准的文本定位、选择、编辑:
# 获取当前光标对象 cursor = self.text_edit.textCursor() # 1. 光标定位 cursor.movePosition(cursor.Start) # 移到文本开头 cursor.movePosition(cursor.End) # 移到文本结尾 cursor.movePosition(cursor.Down, cursor.MoveAnchor, 5) # 向下移动5行 self.text_edit.setTextCursor(cursor) # 应用光标位置 # 2. 文本选择 cursor.setPosition(10) # 起始位置 cursor.movePosition(cursor.Right, cursor.KeepAnchor, 5) # 向右选择5个字符 selected_text = cursor.selectedText() # 获取选中的文本 # 3. 替换选中的文本 cursor.insertText("替换后的内容") # 4. 选中所有文本 self.text_edit.selectAll()信号与槽(核心交互)
QPlainTextEdit 提供丰富的信号,用于响应文本变化、光标移动等事件:
| 信号 | 触发条件 |
|---|---|
textChanged() | 文本内容发生变化时(每次输入 / 删除字符都会触发) |
cursorPositionChanged() | 光标位置改变时 |
selectionChanged() | 选中的文本范围改变时 |
undoAvailable(bool) | 撤销操作可用 / 不可用时 |
redoAvailable(bool) | 重做操作可用 / 不可用时 |
示例:响应文本变化和光标移动
import sys from PySide6.QtCore import QMetaObject, Slot from PySide6.QtWidgets import QPlainTextEdit, QApplication class MyTextEdit(QPlainTextEdit): def __init__(self, parent=None): super().__init__(parent) self.setupUI() QMetaObject.connectSlotsByName(self) def setupUI(self): self.textChanged.connect(self.on_textChanged) self.cursorPositionChanged.connect(self.on_cursorPositionChanged) @Slot() def on_textChanged(self): """文本变化时触发:统计字符数和行数""" text = self.toPlainText() char_count = len(text) line_count = self.document().blockCount() self.setWindowTitle(f"字符数:{char_count} | 行数:{line_count}") @Slot() def on_cursorPositionChanged(self): """光标移动时触发:显示当前行/列""" cursor = self.textCursor() line = cursor.blockNumber() + 1 # 行号从1开始显示 col = cursor.columnNumber() + 1 # 列号从1开始显示 print(f"当前位置:第 {line} 行,第 {col} 列") app = QApplication(sys.argv) text_edit = MyTextEdit() text_edit.show() sys.exit(app.exec())高级配置
1. 换行模式
控制文本超出控件宽度时的换行行为:
# 可选模式: # NoWrap:不换行(横向滚动条出现) # WidgetWidth:按控件宽度自动换行(默认) # FixedPixelWidth:按固定像素宽度换行 # FixedColumnWidth:按固定字符数换行 self.text_edit.setLineWrapMode(QPlainTextEdit.WidgetWidth)2. 滚动控制
# 自动滚动到末尾(如日志输出场景) self.text_edit.verticalScrollBar().setValue( self.text_edit.verticalScrollBar().maximum() ) # 滚动到指定行 def scroll_to_line(line_num): block = self.text_edit.document().findBlockByNumber(line_num) if block.isValid(): self.text_edit.scrollToBlock(block)3. 只读模式与编辑权限
self.text_edit.setReadOnly(True) # 只读(无法编辑,可选中/复制) self.text_edit.setUndoRedoEnabled(False) # 禁用撤销/重做 self.text_edit.setAcceptRichText(False) # 拒绝粘贴富文本(仅保留纯文本)4. 语法高亮(扩展)
结合QSyntaxHighlighter实现代码 / 日志的语法高亮,示例(Python 关键字高亮):
import sys from PySide6.QtGui import QSyntaxHighlighter, QTextCharFormat, QColor from PySide6.QtWidgets import QTextEdit, QApplication class PythonHighlighter(QSyntaxHighlighter): def __init__(self, parent=None): super().__init__(parent) # 定义高亮格式 keyword_format = QTextCharFormat() keyword_format.setForeground(QColor("#FF7F00")) # 橙色 keyword_format.setFontWeight(75) # 加粗 # Python 关键字列表 self.keywords = [ "and", "as", "assert", "break", "class", "continue", "def", "del", "elif", "else", "except", "False", "finally", "for", "from", "global", "if", "import", "in", "is", "lambda", "None", "nonlocal", "not", "or", "pass", "raise", "return", "True", "try", "while", "with", "yield" ] # 存储高亮规则(正则表达式 + 格式) self.highlight_rules = [] for keyword in self.keywords: pattern = rf"\b{keyword}\b" # 单词边界匹配 self.highlight_rules.append((pattern, keyword_format)) def highlightBlock(self, text): """对每一行文本应用高亮规则""" for pattern, format in self.highlight_rules: import re for match in re.finditer(pattern, text): start, end = match.span() self.setFormat(start, end - start, format) class myTextEdit(QTextEdit): def __init__(self, parent=None): super().__init__(parent) self.setupUI() def setupUI(self): self.highlighter = PythonHighlighter(self.document()) if __name__ == "__main__": app = QApplication(sys.argv) text_edit = myTextEdit() text_edit.show() sys.exit(app.exec())常见场景示例
1. 日志输出窗口(自动滚动 + 只读)
class LogWindow(QMainWindow): def __init__(self): super().__init__() self.text_edit = QPlainTextEdit() self.text_edit.setReadOnly(True) self.text_edit.setLineWrapMode(QPlainTextEdit.NoWrap) self.setCentralWidget(self.text_edit) def append_log(self, log_text): """追加日志并自动滚动到末尾""" self.text_edit.appendPlainText(log_text) # 自动滚动 scroll_bar = self.text_edit.verticalScrollBar() scroll_bar.setValue(scroll_bar.maximum()) # 使用 log_window = LogWindow() log_window.append_log("[INFO] 程序启动成功") log_window.append_log("[ERROR] 数据库连接失败")2. 带行号的代码编辑器(简化版)
import sys from PySide6.QtGui import QPainter, QColor from PySide6.QtWidgets import QWidget, QTextEdit, QHBoxLayout, QPlainTextEdit, QApplication from PySide6.QtCore import Qt class LineNumberWidget(QWidget): """行号显示控件""" def __init__(self, text_edit, parent=None): super().__init__(parent) self.text_edit = text_edit self.text_edit.cursorPositionChanged.connect(self.update) def paintEvent(self, event): painter = QPainter(self) painter.fillRect(event.rect(), QColor("#F0F0F0")) # 行号背景色 # 获取可见的行范围 block = self.text_edit.firstVisibleBlock() block_number = block.blockNumber() top = self.text_edit.blockBoundingGeometry(block).translated(self.text_edit.contentOffset()).top() bottom = top + self.text_edit.blockBoundingRect(block).height() # 绘制行号 while block.isValid() and top <= event.rect().bottom(): if block.isVisible() and bottom >= event.rect().top(): number = str(block_number + 1) painter.drawText(0, int(top), self.width() - 5, self.text_edit.fontMetrics().height(), Qt.AlignRight, number) block = block.next() top = bottom bottom = top + self.text_edit.blockBoundingRect(block).height() block_number += 1 # 组合行号和编辑区 class CodeEditor(QWidget): def __init__(self): super().__init__() layout = QHBoxLayout(self) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) self.text_edit = QPlainTextEdit() self.line_number = LineNumberWidget(self.text_edit) self.line_number.setFixedWidth(40) # 行号宽度 layout.addWidget(self.line_number) layout.addWidget(self.text_edit) if __name__ == '__main__': app = QApplication(sys.argv) editor = CodeEditor() editor.show() sys.exit(app.exec())注意事项
- 性能优化:处理超大型文本(如 10 万行以上)时,建议关闭实时更新(如
textChanged信号),批量操作后再刷新; - 编码问题:读取 / 保存文本时需指定编码(如 UTF-8),避免乱码;
- 与 QTextEdit 区分:QTextEdit 支持富文本,但性能低;QPlainTextEdit 仅纯文本,适合大文本场景;
- 撤销 / 重做:默认开启,可通过
setUndoRedoEnabled(False)禁用,避免内存占用过高; - 换行符兼容:不同系统换行符(\n/\r\n)可通过
document().setPlainText()自动适配。
总结
QPlainTextEdit 是 PySide6 中处理纯文本的核心控件,通过基础文本操作、光标控制、信号响应可满足大部分纯文本编辑需求,结合语法高亮、行号控件等扩展可实现代码编辑器、日志查看器等复杂功能。重点掌握其轻量级特性、行级操作和信号槽机制,即可灵活应用于各类文本处理场景。
3. QTextEdit(多行文本框)
QTextEdit是 PySide6 中功能强大的多行富文本编辑控件,支持纯文本、HTML 富文本的输入 / 显示,还提供文本格式化、撤销 / 重做、查找替换等高级功能,是实现记事本、富文本编辑器、聊天框、文档预览等场景的核心组件。
- 核心作用:多行富文本 / 纯文本输入(如备注、编辑器)。
核心特性:
- 双模式支持:可作为纯文本编辑器(类似
QPlainTextEdit)或富文本编辑器(支持字体、颜色、段落格式); - 内容操作:支持文本插入、删除、替换,以及撤销 / 重做、复制 / 粘贴;
- 格式控制:可设置选中文本的字体、颜色、对齐方式、列表样式等;
- 布局与滚动:自动换行、水平 / 垂直滚动,支持自定义页边距;
- 信号反馈:文本变化、光标移动、选择范围变更等信号,满足交互需求;
- 只读模式:可切换为只读,用于富文本内容展示(如帮助文档)。
基础用法
基本初始化与布局
import sys from PySide6.QtWidgets import ( QApplication, QWidget, QTextEdit, QVBoxLayout, QPushButton, QHBoxLayout ) from PySide6.QtGui import QFont, QColor from PySide6.QtCore import Qt class TextEditDemo(QWidget): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("QTextEdit 详解") self.resize(800, 600) # 1. 创建核心控件 self.text_edit = QTextEdit() # 2. 基础配置 self.text_edit.setPlaceholderText("请输入内容(支持富文本)") # 占位提示 self.text_edit.setFont(QFont("Microsoft YaHei", 12)) # 默认字体 self.text_edit.setLineWrapMode(QTextEdit.WidgetWidth) # 按控件宽度自动换行 self.text_edit.setTabStopDistance(40) # Tab 缩进距离(像素) # 3. 功能按钮布局 btn_layout = QHBoxLayout() # 纯文本/富文本切换 self.btn_plain = QPushButton("纯文本模式") self.btn_plain.clicked.connect(self.switch_plain_mode) # 设置选中文本颜色 btn_color = QPushButton("选中文本设为红色") btn_color.clicked.connect(self.set_text_color) # 插入图片 btn_image = QPushButton("插入图片") btn_image.clicked.connect(self.insert_image) # 清空内容 btn_clear = QPushButton("清空") btn_clear.clicked.connect(self.text_edit.clear) btn_layout.addWidget(self.btn_plain) btn_layout.addWidget(btn_color) btn_layout.addWidget(btn_image) btn_layout.addWidget(btn_clear) # 4. 主布局 main_layout = QVBoxLayout() main_layout.addLayout(btn_layout) main_layout.addWidget(self.text_edit) self.setLayout(main_layout) # 5. 绑定信号(监听文本变化) self.text_edit.textChanged.connect(self.on_text_changed) def switch_plain_mode(self): """切换纯文本/富文本模式""" if self.text_edit.acceptRichText(): self.text_edit.setAcceptRichText(False) # 禁用富文本(纯文本模式) self.btn_plain.setText("富文本模式") else: self.text_edit.setAcceptRichText(True) # 启用富文本 self.btn_plain.setText("纯文本模式") def set_text_color(self): """设置选中文本颜色为红色""" # 获取文本光标(操作选中文本的核心) cursor = self.text_edit.textCursor() if cursor.hasSelection(): # 有选中内容 # 设置选中文本格式 char_format = cursor.charFormat() char_format.setForeground(QColor(255, 0, 0)) # 红色 cursor.setCharFormat(char_format) def insert_image(self): """插入图片到光标位置""" # 替换为本地图片路径(支持 PNG/JPG 等) img_path = "demo.png" # 插入图片(参数:图片路径、替代文本、尺寸) self.text_edit.insertHtml(f'<img src="{img_path}" width="200" height="150"/>') def on_text_changed(self): """文本变化时触发(实时统计字符数)""" # 获取纯文本内容(排除富文本标签) plain_text = self.text_edit.toPlainText() char_count = len(plain_text) self.setWindowTitle(f"QTextEdit 详解 - 字符数:{char_count}") if __name__ == "__main__": app = QApplication(sys.argv) demo = TextEditDemo() demo.show() sys.exit(app.exec())核心功能与 API 详解
1. 内容操作(文本 / 富文本)
| 方法 | 说明 | 示例 |
|---|---|---|
setPlainText(text) | 设置纯文本内容(覆盖原有内容) | text_edit.setPlainText("Hello World") |
toPlainText() | 获取纯文本内容(忽略富文本格式) | text = text_edit.toPlainText() |
setHtml(html) | 设置富文本内容(HTML 格式) | text_edit.setHtml("<h1>标题</h1><p>段落</p>") |
toHtml() | 获取富文本的 HTML 源码 | html = text_edit.toHtml() |
insertPlainText(text) | 在光标位置插入纯文本 | text_edit.insertPlainText("插入内容") |
insertHtml(html) | 在光标位置插入富文本 | text_edit.insertHtml("<b>加粗</b>") |
append(text) | 追加文本(自动换行,支持富文本) | text_edit.append("新的一行") |
clear() | 清空所有内容 | text_edit.clear() |
undo()/redo() | 撤销 / 重做操作 | text_edit.undo() |
copy()/cut()/paste() | 复制 / 剪切 / 粘贴 | text_edit.copy() |
2. 格式控制(选中文本 / 全局)
(1)字符格式(字体、颜色、样式)
from PySide6.QtWidgets import QApplication, QMainWindow, QTextEdit from PySide6.QtGui import QFont, QColor, QTextCursor import sys class MainWindow(QMainWindow): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("富文本编辑器") self.resize(800, 600) # 设置窗口大小(避免控件太小看不到效果) # 1. 创建核心控件 self.text_edit = QTextEdit() # 2. 基础配置 self.text_edit.setPlaceholderText("请输入内容(支持富文本)") self.text_edit.setLineWrapMode(QTextEdit.LineWrapMode.WidgetWidth) self.text_edit.setTabStopDistance(40) self.text_edit.setAcceptRichText(True) # 3. 设置默认字符格式 # 方式1:直接给 QTextEdit 设置默认格式(推荐,对所有新输入文本生效) # default_format = self.text_edit.currentCharFormat() # 获取控件默认格式 # default_format.setFont(QFont("Microsoft YaHei UI", 36, QFont.Weight.Bold)) # 字体 # default_format.setForeground(QColor("#ff0000")) # 字体颜色 # default_format.setBackground(QColor("#EEEE00")) # 背景色 # self.text_edit.setCurrentCharFormat(default_format) # 应用到控件 # (可选)方式2:通过光标设置后,将光标放回控件 cursor = self.text_edit.textCursor() char_format = cursor.charFormat() char_format.setFont(QFont("Microsoft YaHei UI", 36, QFont.Weight.Bold)) char_format.setForeground(QColor("#ff0000")) char_format.setBackground(QColor("#EEEEaa")) cursor.setCharFormat(char_format) self.text_edit.setTextCursor(cursor) # 关键:将修改后的光标放回控件 # 4. 将控件设置为主窗口中心部件(必须,否则控件不显示) self.setCentralWidget(self.text_edit) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())(2)段落格式(对齐、缩进、行距)
通过QTextBlockFormat控制段落样式:
from PySide6.QtCore import Qt from PySide6.QtWidgets import QApplication, QMainWindow, QTextEdit from PySide6.QtGui import QFont, QColor, QTextCursor, QTextBlockFormat import sys class MainWindow(QMainWindow): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.setWindowTitle("富文本编辑器") self.resize(800, 600) # 设置窗口大小(避免控件太小看不到效果) # 1. 创建核心控件 self.text_edit = QTextEdit() # 2. 基础配置 self.text_edit.setPlaceholderText("请输入内容(支持富文本)") self.text_edit.setLineWrapMode(QTextEdit.LineWrapMode.WidgetWidth) self.text_edit.setTabStopDistance(40) self.text_edit.setAcceptRichText(True) # 1. 创建段落格式对象 block_format = QTextBlockFormat() block_format.setAlignment(Qt.AlignCenter) # 居中对齐 block_format.setLeftMargin(20) # 左缩进 block_format.setLineHeight(200.0, QTextBlockFormat.ProportionalHeight.value) # 行距150% # 2. 应用到当前段落 cursor = self.text_edit.textCursor() cursor.setBlockFormat(block_format) # 4. 将控件设置为主窗口中心部件(必须,否则控件不显示) self.setCentralWidget(self.text_edit) if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())(3)列表样式(有序 / 无序列表)
import sys from PySide6.QtWidgets import QApplication, QMainWindow, QTextEdit from PySide6.QtGui import QTextCursor, QTextListFormat class MainWindow(QMainWindow): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.text_edit = QTextEdit(self) self.setCentralWidget(self.text_edit) # 获取当前文本光标 cursor = self.text_edit.textCursor() # 设置列表模式 list_format = QTextListFormat() # list_format.setStyle(QTextListFormat.ListDecimal) # 设置列表样式为有序数字列表,或者: list_format.setStyle(QTextListFormat.ListDisc) # 设置列表样式为无序圆点列表 cursor.createList(list_format) if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() sys.exit(app.exec())(4) 光标与选择操作
QTextCursor是操作QTextEdit内容的核心工具,用于定位光标、选择文本、修改格式:
import sys from PySide6.QtWidgets import QApplication, QMainWindow, QTextEdit from PySide6.QtGui import QTextCursor, QTextListFormat class MainWindow(QMainWindow): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.text_edit = QTextEdit(self) self.setCentralWidget(self.text_edit) self.text_edit.setText("0123456789abcdefg") # 获取当前文本光标 # 1. 获取当前光标 cursor = self.text_edit.textCursor() # 2. 光标定位 cursor.movePosition(QTextCursor.Start) # 移到文本开头(End/NextLine/PreviousWord 等) cursor.setPosition(10) # 移到第10个字符位置 # 3. 选择文本(从位置5到位置15) cursor.setPosition(5) cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, 10) # 4. 判断是否有选中内容 if cursor.hasSelection(): selected_text = cursor.selectedText() # 获取选中的文本 print(f"选中内容:{selected_text}") # 5. 替换选中内容 cursor.insertText("替换后的内容") if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() sys.exit(app.exec())3. 布局与显示配置
| 方法 | 说明 | 可选值 |
|---|---|---|
setLineWrapMode(mode) | 自动换行模式 | QTextEdit.NoWrap(不换行)、QTextEdit.WidgetWidth(按控件宽度)、QTextEdit.FixedPixelWidth(固定像素宽度) |
setWordWrapMode(mode) | 单词换行规则 | QTextOption.WrapAnywhere(任意位置换行)、QTextOption.WrapAtWordBoundaryOrAnywhere(单词边界优先) |
setReadOnly(bool) | 只读模式(仅显示,不可编辑) | True/False |
setContentsMargins(left, top, right, bottom) | 内容页边距 | text_edit.setContentsMargins(10, 10, 10, 10) |
setVerticalScrollBarPolicy(policy) | 垂直滚动条策略 | Qt.ScrollBarAlwaysOn/Qt.ScrollBarAsNeeded/Qt.ScrollBarAlwaysOff |
4. 常用信号
| 信号 | 触发场景 |
|---|---|
textChanged() | 文本内容发生任何变化(插入 / 删除 / 格式修改) |
cursorPositionChanged() | 光标位置移动或选择范围变更 |
selectionChanged() | 选中的文本范围变更 |
editingFinished() | 编辑完成(失去焦点 / 回车) |
copyAvailable(bool) | 可复制内容状态变化(True = 有可复制内容) |
典型应用场景
1. 简单富文本编辑器
import sys from PySide6.QtGui import QFont from PySide6.QtWidgets import QApplication, QMainWindow, QTextEdit class MainWindow(QMainWindow): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.text_edit = QTextEdit(self) self.setCentralWidget(self.text_edit) # 获取当前文本光标 # 1. 获取当前光标和字符格式 self.cursor = self.text_edit.textCursor() self.char_format = self.cursor.charFormat() # 2. 设置字体加粗 if not self.char_format.font().bold(): self.char_format.setFontWeight(QFont.Bold) self.cursor.setCharFormat(self.char_format) self.text_edit.setTextCursor(self.cursor) print(self.char_format.font().bold()) # 3. 设置斜体 if not self.char_format.font().italic(): self.char_format.setFontItalic(True) self.cursor.setCharFormat(self.char_format) self.text_edit.setTextCursor(self.cursor) print(self.char_format.font().italic()) # 4. 设置下划线 if not self.char_format.font().underline(): self.char_format.setFontUnderline(True) self.cursor.setCharFormat(self.char_format) self.text_edit.setTextCursor(self.cursor) print(self.char_format.font().underline()) if __name__ == "__main__": app = QApplication([]) window = MainWindow() window.show() sys.exit(app.exec())2. 聊天消息框(只读 + 富文本展示)
import sys from PySide6.QtGui import QFont, QTextCursor from PySide6.QtWidgets import QApplication, QMainWindow, QTextEdit class MainWindow(QMainWindow): def __init__(self): super().__init__() self.init_ui() def init_ui(self): self.text_edit = QTextEdit(self) self.setCentralWidget(self.text_edit) # 获取当前文本光标 # 1. 获取当前光标和字符格式 self.cursor = self.text_edit.textCursor() self.char_format = self.cursor.charFormat() # 示例:展示带头像和昵称的聊天消息 def add_chat_msg(nickname, content, avatar_path, text_edit): # 构造富文本消息 html = f""" <div style="margin: 5px 0;"> <img src="{avatar_path}" width="30" height="30" style="border-radius: 50%; vertical-align: middle;"/> <span style="font-weight: bold; margin: 0 5px;">{nickname}:</span> <span>{content}</span> </div> """ text_edit.append(html) # 自动滚动到底部 text_edit.moveCursor(QTextCursor.End) if __name__ == "__main__": app = QApplication([]) window = MainWindow() nickname = "拯救地球的怪兽" content = "你好,世界!" avatar_path = "avatar.png" text_edit = window.text_edit add_chat_msg(nickname, content, avatar_path, text_edit) window.show() sys.exit(app.exec())3. 文本查找与替换
from PySide6.QtGui import QTextDocument # 查找文本 def find_text(text): # 从当前光标位置查找 found = text_edit.find(text, QTextDocument.FindWholeWords) # 匹配整词 if not found: # 未找到则回到开头重新查找 text_edit.moveCursor(QTextCursor.Start) found = text_edit.find(text) return found # 替换选中的文本 def replace_text(old_text, new_text): if find_text(old_text): cursor = text_edit.textCursor() cursor.insertText(new_text)4. 样式定制(StyleSheet)
通过 CSS 样式表自定义QTextEdit外观:
text_edit.setStyleSheet(""" QTextEdit { border: 1px solid #CCCCCC; /* 边框 */ border-radius: 6px; /* 圆角 */ padding: 8px; /* 内边距 */ background-color: #FFFFFF; /* 背景色 */ color: #333333; /* 文本颜色 */ font-size: 12px; } QTextEdit:focus { border-color: #0066CC; /* 聚焦时边框变色 */ outline: none; /* 去除默认聚焦外框 */ } QTextEdit:read-only { background-color: #F5F5F5; /* 只读模式背景色 */ color: #666666; } """)与 QPlainTextEdit 的区别
| 特性 | QTextEdit | QPlainTextEdit |
|---|---|---|
| 核心定位 | 富文本编辑(支持 HTML、图片、格式) | 纯文本编辑(轻量、高性能) |
| 性能 | 大量纯文本时性能较低 | 适合大文本(如日志、代码) |
| 格式支持 | 字符 / 段落 / 列表 / 图片 / 表格 | 仅基础文本(无富文本) |
| 适用场景 | 富文本编辑器、聊天框、文档预览 | 代码编辑器、日志查看器 |
最佳实践
- 性能优化:
- 处理大文本(10 万 + 字符)时优先用
QPlainTextEdit; - 批量修改文本时先调用
text_edit.blockSignals(True)关闭信号,修改后恢复,避免频繁触发textChanged。
- 处理大文本(10 万 + 字符)时优先用
- 富文本兼容性:
- 自定义富文本时尽量使用标准 HTML 标签(
<b>/<i>/<img>等),避免兼容问题; - 读取富文本时优先用
toHtml(),写入时用setHtml()保证格式完整。
- 自定义富文本时尽量使用标准 HTML 标签(
- 用户体验:
- 只读模式下设置
setCursor(Qt.IBeamCursor),保持光标样式一致; - 长文本场景添加 “自动滚动到底部” 选项,提升阅读体验。
- 只读模式下设置
- 资源管理:
插入的图片若为本地文件,需保证路径有效;也可将图片嵌入 HTML(base64 编码)避 免路径依赖。