QTextEdit多行富文本编辑器
- 描述
- 是一个高级的WYSIWYG(What You See Is What You Get 所见即所得)查看器/编辑器,支持使用HTML样式标签的富文本格式。
- 支持的HTML4标签子集: Supported HTML Subset | Qt GUI 5.15.13
- 如果不够, 可以考虑使用WebKit(Qt中专门的浏览器,可以加载HTML样式标签的富文本内容)
- 它经过优化,可以处理大型文档并快速响应用户输入。
- 适用于段落和字符(如果文本太大而无法在文本编辑的视口中查看,则会出现滚动条)
- 文本编辑可以加载纯文本和富文本文件(可以显示图像,列表和表格)
- 是一个高级的WYSIWYG(What You See Is What You Get 所见即所得)查看器/编辑器,支持使用HTML样式标签的富文本格式。
- 继承自:QAbstractScrollArea
- 功能作用
- 占位提示文本
setPlaceholderText(str) # 设置占位提示文本内容 placeholderText() -> str # 获取置占位提示文本内容
- 内容设置
- 两种方案:
- 1、通过QTextEdit对象自带的方法
- 2、通过文本光标对文本文档进行操作
- 方案一:QTextEdit自带方法
# 普通文本 setPlainText(str) # 设置普通文本内容 insertPlainText(str) # 插入普通文本内容 toPlainText() -> str # 获取当前文本内容 # HTML富文本 setHtml(str) # 设置HTML文本内容 insertHtml(str) # 插入HTML文本内容 toHtml() -> str # 获取HTML文本内容,返回的是完整的HTML结构代码 # 设置文本(自动判定类型) setText(str) # 设置文本内容 # 追加文本内容 append(str) # 在内容最后面添加文本内容,会自动判断类型 # 清空内容 clear() # 清空文本框中的所有内容
- 方案二:文本光标(类似于文本编辑器)
- 通过文本光标, 可以操作编辑 文本文档 对象
- 整个文本编辑器, 其实就是为编辑 这个文本文档 提供了一个可视化的界面
- 简单理解, 可以比喻成 一个doc文档, 使用word软件打开了这个文档, 你可以随意编辑
- 文本光标详细讲解
- 两种方案:
- 自动格式化
setAutoFormatting(QTextEdit.AutoFormatting) # 设置自动格式化 # 参数:QTextEdit.AutoFormatting QTextEdit.AutoNone # 不要做任何自动格式化。 QTextEdit.AutoBulletList # 自动创建项目符号列表 # (例如,当用户在最左侧列中输入星号('*')时,或在现有列表项中按Enter键。 QTextEdit.AutoAll # 应用所有自动格式。目前仅支持自动项目符号列表。 autoFormatting() -> QTextEdit.AutoFormatting # 获取自动格式化对象
- 软换行模式(自动换行模式)
- 设置当用户输入内容过多时, 是否进行软换行, 以及如何进行软换行
setLineWrapMode(QTextEdit.LineWrapMode) # 设置软换行模式 lineWrapMode() -> QTextEdit.LineWrapMode # 获取软换行模式 setWordWrapMode(self, QTextOption.WrapMode) # 设置单词换行模式 wordWrapMode(self) -> QTextOption.WrapMode # 获取单词换行模式 # 补充 QTextEdit.LineWrapMode QTextEdit.NoWrap # 没有软换行, 超过宽度后, 会产生水平滚动条 QTextEdit.WidgetWidth # 以控件的宽度为限制,但会保持单词的完整性 QTextEdit.FixedPixelWidth # 按指定像素宽度进行软换行,需要配合下面的方法使用 setLineWrapColumnOrWidth(int) # 设置指定的像素宽度 lineWrapColumnOrWidth() -> int # 获取设置的固定像素宽度 QTextEdit.FixedColumnWidth # 按指定列数宽度进行软换行(字符个数) setLineWrapColumnOrWidth(int) # 设置指定的列数 lineWrapColumnOrWidth() -> int # 获取设置的固定列数 QTextOption.WrapMode QTextOption.WordWrap # 常用,保持单词完整性 QTextOption.WrapAnywhere # 常用,宽度够了之后, 随意在任何位置换行 QTextOption.NoWrap # 文本根本没有包装。 QTextOption.ManualWrap # 与QTextOption.NoWrap相同 QTextOption.WrapAtWordBoundaryOrAnywhere # 尽可能赶在单词的边界, 否则就在任意位置换行
- 覆盖模式
- 切换覆盖模式, 修改文本内容
- 设置为True后,光标处与文本内容中间时输入内容,会覆盖掉后面的内容(不需要选中)
- 类似于按下电脑上的Insert按钮后输入内容的状态
setOverwriteMode(bool) # 设置覆盖模式。True为开启覆盖模式,False为插入模式 overwriteMode() -> bool # 获取覆盖模式状态
- 光标设置
- 一般是结合覆盖模式来做, 标识光标的宽度, 给用户以提醒
setCursorWidth(int) # 设置光标宽度 cursorWidth() # 获取光标宽度 cursorRect() -> QRect # 获取光标矩形范围,返回(x坐标,y坐标,宽度,高度) # x、y坐标是相对于QTextEdit对象的坐标
- 对齐方式
setAlignment(Qt.Alignment) # 设置段落对齐方式 # 参数 Qt.Alignment Qt.AlignLeft # 默认,靠左对齐 Qt.AlignRight # 靠右对齐 Qt.AlignCenter # 居中对齐 alignment() -> Qt.Alignment # 获取对齐方式
- 字体格式
setFontFamily(family_str) # 设置字体家族 fontFamily() # 获取设置的字体 setFontWeight(int) # 设置字体粗细(通过下面枚举) QFont.Thin # 细小 QFont.ExtraLight # 稍微加粗 QFont.Light QFont.Normal # 标准的 QFont.Medium # 中等 QFont.DemiBold # 半粗体 QFont.Bold # 粗体 QFont.ExtraBold # 特粗体 QFont.Black # 黑体 fontWeight() # 获取字体粗细 setFontItalic(bool) # 设置字体是否倾斜 fontItalic() # 获取字体是否倾斜 setFontPointSize(float) # 设置字体尺寸 fontPointSize() # 获取字体尺寸 setFontUnderline(bool) # 设置字体是否加下划线 fontUnderline() # 获取字体是否加下划线 setCurrentFont(QFont) # 通过QFont对象统一设置字体格式 currentFont() -> QFont # 获取设置的字体格式QFont对象 # QFont对象里面有很多方法可以设置字体格式,也可以通过字体格式选择框获取QFont对象 # 小技巧:弹出字体格式选择框 QFontDialog.getFont() # 查看可用的字体 # 返回一个QFont对象和选择结果<确定:True,取消:False>的元组 # (<PyQt5.QtGui.QFont object at 0x000001DE2F386890>, True) # (<PyQt5.QtGui.QFont object at 0x000001DE2F386890>, False)
- 颜色设置
setTextBackgroundColor(QColor) # 通过QColor对象设置文本背景颜色 textBackgroundColor() -> QColor # 获取当前文本背景颜色 setTextColor(QColor) # 通过QColor对象设置文本颜色 textColor() -> QColor # 获取当前文本颜色
- 当前的字符格式
- 针对于部分字符, 设置特定的格式
- 将新文本插入格式时使用的char格式。
- 如果编辑器有选择的文本内容,则char格式直接应用于选择
setCurrentCharFormat(QTextCharFormat) # 设置字体格式,会覆盖掉之前设置的格式 mergeCurrentCharFormat(QTextCharFormat) # 合并字符格式 currentCharFormat() -> QTextCharFormat # 获取字体格式,返回QTextCharFormat对象 # 补充 QTextCharFormat 描述 提供了一种字符格式信息 文档中文本的字符格式指定文本的可视属性,以及有关其在超文本文档中的角色的信息 设置字体格式 setFont(QFont) # 通过QFont对象统一设置字体格式 font() -> QFont # 获取字体格式的QFont对象 setFontFamily(family_str) # 设置字体家族 fontFamily() -> str # 获取字体家族 setFontPointSize(float) # 设置字体大小 fontPointSize() -> float # 获取字体大小 setFontWeight(int) # 设置字体粗细 fontWeight() -> int # 获取字体粗细 setFontOverline(bool) # 设置字体上划线 fontOverline() -> bool # 获取字体是否设置上划线 setFontStrikeOut(bool) # 设置字体中划线(删除线) fontStrikeOut() -> bool # 获取字体是否设置中划线 setFontUnderline(bool) # 获取字体下划线 fontUnderline() -> bool # 获取字体是否设置下划线 字体大小写 setFontCapitalization(QFont.Capitalization) # 设置字体大小写格式 fontCapitalization() -> QFont.Capitalization # 获取字体大小写格式 # 参数:QFont.Capitalization QFont.MixedCase # 正常的文本呈现 QFont.AllUppercase # 以全大写类型呈现的文本 QFont.AllLowercase # 以全小写类型呈现的文本 QFont.SmallCaps # 以小型大写字母呈现的文本 QFont.Capitalize # 单词的首字符为大写字符 颜色 setForeground(QColor(100, 200, 150)) # 通过QColor对象设置字体颜色 超链接 setAnchorHref("http://www.itlike.com") # 设置超链接 anchorHref() -> str # 获取超链接
- 常用编辑操作
copy() # 复制 paste() # 粘贴 canPaste() -> bool # 判断是否可以粘贴 setUndoRedoEnabled(bool) # 设置是否允许撤回操作 redo() undo() # 撤销 selectAll() # 选中全部 find(str, QTextDocument.FindFlags | QTextDocument.FindFlag | QTextDocument.FindFlags) -> bool # 参数:QTextDocument.FindFlags QTextDocument.FindBackward # 向后(左)搜索而不是向前搜索。 QTextDocument.FindCaseSensitively # 区分大小写的查找操作,默认不区分大小写。 QTextDocument.FindWholeWords # 使查找匹配仅完整的单词。
- 滚动到锚点
scrollToAnchor(p_str) # 设置滚动到指定锚点处 # 需要提前设置锚点 <a name="锚点名称" href="#锚点内容"> xxx </a>
- 只读设置
- 设置为只读模式后,并不能限制通过代码对内容的增删改
setReadOnly(self, bool) # 设置只读模式 isReadOnly() -> bool # 判断是否是只读模式
- tab控制
setTabChangesFocus(bool) # 默认是False,设置按下Tab键是否是改变焦点 setTabStopDistance(p_float) # 设置一个Tab制表符的宽度,默认80(像素)(可以设置小数) setTabStopWidth(p_int) # 设置一个Tab制表符的宽度(只能设置整数) tabStopDistance(self) -> float # 获取Tab键制表符的宽度,返回float tabStopWidth() -> int # 获取Tab键制表符的宽度,返回int
- 锚点获取超链接
- 通过设置锚点获取超链接,实现点击超链接后打开网站
- 这里需要通过监听点击事件消息,但是QTextEdit控件没有点击事件消息
- 那么,我们需要通过子类化重写该对象的点击事件
anchorAt(QPoint) -> str # 返回位置pos处的锚点的引用,如果该点处不存在锚点,则返回空字符串 # 单击超链接后, 打开对应的网页 QDesktopServices.openUrl(QUrl(urlString)) # 打开指定链接地址
- 示例
from PyQt5.Qt import * import sys class MyQTextEdit(QTextEdit): def mousePressEvent(self, me): super(MyQTextEdit, self).mousePressEvent(me) # me.pos() 获取到鼠标点击处的坐标对象QPoint # 通过anchorAt获取到坐标点的锚点引用内容,返回str url = self.anchorAt(me.pos()) if len(url) > 0: # 通过QDesktopServices.openUrl打开网址 QDesktopServices.openUrl(QUrl(url)) app = QApplication(sys.argv) window = QWidget() window.resize(500, 500) window.setWindowTitle('QTextEdot-锚点获取') """ QTextEdit本身没有点击事件消息 所以需要通过子类化重写单击事件(自定义类继承该类) class MyQTextEdit(QTextEdit) """ te = MyQTextEdit(window) te.resize(300, 200) te.move(100,100) te.setText('<a href="https://www.baidu.com">百度一下,你就知道</a>') window.show() sys.exit(app.exec_())
- 可用信号
textChanged() # 文本内容发生改变时, 发射的信号 selectionChanged() # 选中内容发生改变时, 发射的信号 cursorPositionChanged() # 光标位置发生改变时, 发射的信号 currentCharFormatChanged(QTextCharFormat) # 当前额字符格式发生改变时, 发射的信号 copyAvailable(bool yes) # 复制可用时 redoAvailable(bool available) # 重做可用时 undoAvailable(bool available) # 撤销可用时
- 示例代码
- 示例1:QTextEdit-创建使用
from PyQt5.Qt import * import sys app = QApplication(sys.argv) window = QWidget() window.resize(500, 500) window.setWindowTitle('QTextEdit-创建使用') te = QTextEdit(window) te.move(50,50) te.resize(400, 100) # 设置占位提示文本内容 te.setPlaceholderText('请输入详细信息') # # 获取占位提示文本内容 # print(te.placeholderText()) # # 设置普通文本内容 # te.setPlainText('<H1>设置普通文本内容</H1>') # # 插入普通文本内容,在光标处 # te.insertPlainText('<H6>插入普通文本内容</H6>') # # 获取普通文本内容 # print(te.toPlainText()) # # # 设置HTML富文本 # te.setHtml('<H1>设置HTML富文本内容</H1>') # # 插入HTML富文本内容,在光标处 # te.insertHtml('<H6>插入HTML富文本内容</H6>') # # 获取HTML富文本内容 # print(te.toHtml()) # 设置文本内容,自动判断类型 te.setText('大家好啊,我是<h2>失心疯</h2>,今年38岁了') # print(te.toPlainText()) # print(te.toHtml()) # 追加文本内容 te.append('我喜欢学习') te.append('<h2>最喜欢Python</h2>') btn = QPushButton('测试按钮',window) btn.move(10,10) # 清空内容 btn.clicked.connect(lambda : te.clear()) window.show() sys.exit(app.exec_())
- 示例2:QTextEdit-自动格式化
from PyQt5.Qt import * import sys class MyQTextEdit(QTextEdit): def mousePressEvent(self, me): super(MyQTextEdit, self).mousePressEvent(me) # me.pos() 获取到鼠标点击处的坐标对象QPoint # 通过anchorAt获取到坐标点的锚点引用内容,返回str url = self.anchorAt(me.pos()) if len(url) > 0: # 通过QDesktopServices.openUrl打开网址 QDesktopServices.openUrl(QUrl(url)) class Windows(QWidget): def __init__(self): super().__init__() self.setWindowTitle('QTextEdit-自动格式化') self.resize(500, 500) self.widget_list() def widget_list(self): self.add_widget() # self.设置创建项目符号列表() # self.软换行设置() # self.设置覆盖模式() # self.切换覆盖模式_光标设置() # self.对齐方式设置() # self.设置字体格式() # self.颜色设置() # self.当前字符格式() # self.常用编辑操作() # self.滚动到锚点() # self.设置只读() # self.Tab键设置() self.锚点获取超链接() def add_widget(self): te1 = QTextEdit(self) self.te1 = te1 self.te1.move(10,10) self.te1.resize(200, 200) te2 = MyQTextEdit(self) self.te2 = te2 self.te2.move(10 + self.te1.width() + 5, 10) self.te2.resize(200, 200) labe1 = QLabel('默认情况', self) labe2 = QLabel('设置格式', self) labe1.move(self.te1.x(), self.te1.y() + self.te1.height() + 5) labe2.move(self.te2.x(), self.te1.y() + self.te2.height() + 5) self.labe1 = labe1 self.labe2 = labe2 btn = QPushButton(self) btn.move(self.labe2.x(), self.labe2.y() + self.labe2.height() + 5) self.btn = btn def 设置创建项目符号列表(self): # 设置自动创建项目符号列表 self.te2.setAutoFormatting(QTextEdit.AutoBulletList) def 软换行设置(self): """ # 程序默认开启软换行,并保持单词完整性 # 设置文本编辑器不进行软换行,超过宽度产生水平滚动条 # self.te2.setLineWrapMode(QTextEdit.NoWrap) # 设置开启软换行,并保持单词完整性 # self.te2.setLineWrapMode(QTextEdit.WidgetWidth) # 设置不保持单词完整性,随意在任何位置换行 # self.te2.setWordWrapMode(QTextOption.WrapAnywhere) # 设置控件按固定像素宽度进行软换行 # self.te2.setLineWrapMode(QTextEdit.FixedPixelWidth) # 设置需要设置的指定像素宽度 # self.te2.setLineWrapColumnOrWidth(100) """ self.te2.setLineWrapMode(QTextEdit.FixedColumnWidth) # 设置控件按固定列数进行软换行(字符个数) self.te2.setLineWrapColumnOrWidth(8) # 设置需要设置的指定列数 def 设置覆盖模式(self): # ****************设置覆盖模式****************** 开始 self.te2.setOverwriteMode(True) # print('是否是覆盖模式:', self.te2.overwriteMode()) # ****************设置覆盖模式****************** 结束 def 切换覆盖模式_光标设置(self): def vm_test(): self.te2.setOverwriteMode(not self.te2.overwriteMode()) if self.te2.overwriteMode(): self.te2.setCursorWidth(10) else: self.te2.setCursorWidth(1) self.te2.setFocus() print('光标宽度:',self.te2.cursorWidth()) print('光标矩形范围:', self.te2.cursorRect()) self.btn.setText('设置光标') self.btn.clicked.connect(vm_test) def 对齐方式设置(self): # ****************对齐方式设置****************** 开始 self.te2.setAlignment(Qt.AlignCenter) # ****************对齐方式设置****************** 结束 def 设置字体格式(self): def selectfont(): # # 设置字体家族 # self.te2.setFontFamily('宋体') # # 设置字体大小 # self.te2.setFontPointSize(20) # # 设置字体粗细 # self.te2.setFontWeight(QFont.Bold) # # 设置字体倾斜 # self.te2.setFontItalic(True) # # 设置字体是否加下划线 # self.te2.setFontUnderline(True) # # self.te1.setFontFamily('宋体') # self.te1.setFontPointSize(20) # self.te1.setFontWeight(QFont.Thin) # self.te1.setFontItalic(True) # self.te1.setFontUnderline(True) # 通过QFont对象统一设置 qfont = QFontDialog.getFont() if qfont[1]: self.te2.setCurrentFont(qfont[0]) self.btn.setText('字体设置') self.btn.clicked.connect(selectfont) def 颜色设置(self): # 设置文本背景颜色 self.te2.setTextBackgroundColor(QColor(200, 10, 10)) # 设置文本字体颜色 self.te2.setTextColor(QColor(10,10,200)) def 当前字符格式(self): # 分开设置 # tcf = QTextCharFormat() # tcf.setFontPointSize(10) # 设置字体大小 # tcf.setFontFamily('微软雅黑') # 设置字体家族 # tcf.setFontWeight(5) # 设置粗细 # tcf.setFontOverline(True) # 设置上划线 # tcf.setFontStrikeOut(True) # 设置中划线 # tcf.setFontUnderline(True) # 设置下划线 # tcf.setFontCapitalization(QFont.MixedCase) # 正常的文本呈现 # tcf.setFontCapitalization(QFont.AllUppercase) # 以全大写类型呈现的文本 # tcf.setFontCapitalization(QFont.AllLowercase) # 以全小写类型呈现的文本 # tcf.setFontCapitalization(QFont.SmallCaps) # 以小型大写字母呈现的文本 # tcf.setFontCapitalization(QFont.Capitalize) # 单词的首字符为大写字符 # tcf.setForeground(QColor(255, 0, 0)) # 设置字体颜色 # tcf.setAnchorHref("https://www.baidu.com") # 设置超链接(没效果) # self.te2.setCurrentCharFormat(tcf) # 通过字体格式选择器统一设置 def btn_test(): font = QFontDialog.getFont() if font[1]: self.te2.setFont(font[0]) self.btn.setText('设置字体') self.btn.clicked.connect(btn_test) def 常用编辑操作(self): # QTextDocument.FindBackward = 1 # QTextDocument.FindCaseSensitively = 2 # QTextDocument.FindWholeWords = 4 def btn_test(): r = self.te2.find('ab',QTextDocument.FindBackward | QTextDocument.FindCaseSensitively | QTextDocument.FindWholeWords) self.te2.setFocus() print(r) self.btn.setText('find') self.btn.clicked.connect(btn_test) def 滚动到锚点(self): # 给文本编辑器添加文本内容,并添加锚点 self.te2.setText('aaa ' * 100 + "<a name='md' href='#maodian'>锚点</a>" + ' bb' * 100) # def btn_test(): self.te2.scrollToAnchor('md') self.te2.setFocus() # print(r) self.btn.setText('滚动到锚点') self.btn.clicked.connect(btn_test) def 设置只读(self): # 给文本编辑器添加文本内容,并添加锚点 self.te2.setText('aaa ' * 100 + "<a name='md' href='#maodian'>锚点</a>" + ' bb' * 100) def btn_test(): # 设置只读 # isReadOnly() 判断是否是只读 self.te2.setReadOnly(not self.te2.isReadOnly()) self.btn.setText('设置只读切换') self.btn.clicked.connect(btn_test) def Tab键设置(self): def btn_test(): # 设置一个Tab制表符的宽度 self.te2.setTabStopDistance(100.5) # self.te2.setTabStopWidth(80) self.te2.setFocus() self.btn.setText('Tab键设置') self.btn.clicked.connect(btn_test) def 锚点获取超链接(self): self.te2.setText('<a href="https://www.baidu.com">百度一下,你就知道</a>') if __name__ == '__main__': app = QApplication(sys.argv) window = Windows() window.show() sys.exit(app.exec_())