QTextEdit多行富文本编辑器

  • 描述
  • 是一个高级的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_())