文字输入类控件用于接收用户文本 / 数值输入,是表单、设置界面的核心组件。
1. QLineEdit(单行文本框)
核心作用:单行文本输入(如用户名、密码、搜索框)。
关键特性:
- 密码模式:setEchoMode(QLineEdit.Password);
- 输入验证:通过 QValidator 限制输入格式(整数、浮点数、正则);
- 占位符提示:setPlaceholderText("请输入用户名");
- 信号:textChanged(str)(实时变化)、editingFinished()(输入完成)。
输入验证示例:
python
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)或富文本编辑器(支持字体、颜色、段落格式); - 内容操作:支持文本插入、删除、替换,以及撤销 / 重做、复制 / 粘贴;
- 格式控制:可设置选中文本的字体、颜色、对齐方式、列表样式等;
- 布局与滚动:自动换行、水平 / 垂直滚动,支持自定义页边距;
- 信号反馈:文本变化、光标移动、选择范围变更等信号,满足交互需求;
- 只读模式:可切换为只读,用于富文本内容展示(如帮助文档)。
基础用法
基本初始化与布局
python
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)字符格式(字体、颜色、样式)
python
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 控制段落样式:
python
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)列表样式(有序 / 无序列表)
python
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 内容的核心工具,用于定位光标、选择文本、修改格式:
python
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. 简单富文本编辑器
python
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. 聊天消息框(只读 + 富文本展示)

python
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. 文本查找与替换
python
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 编码)避 免路径依赖。