在学习了QFrame和QAbstractScrollArea两个父类后,接下来是一个重头戏:QTextEdit。

一.QTextEdit特性

QTextEdit是一个高级的WYSIWYG(What You See Is What You Get所见即所得)编辑/查看器,支持使用HTML4标签子集的富文本格式。

QTextEdit它经过优化,可以处理大型文档并快速响应用户的输入,可以加载纯文本和富文本文件,用来显示图像、列表和表格。

QTextEdit的父类是QAbstractScrollArea,可以通过滚动条调整显示界面。

 二.功能作用

1.提示占位文本

te.setPlaceholderText('占位文本')      #设定占位文本
te.placeholderText()                  #获取占位文本

占位文本是控件的固有特性,在不改变的前提下是不会随着控件内文本的变化而改变的。

2.文本内容设置

由于QTextEdit是支持普通文本和html标签的,分别有两种文本的操作

a.普通文本设定

QTextEdit.setPlainText(str)         #普通文本设定
QTextEdit.insertPlainText(str)      #光标处插入普通文本
QTextEdit.toPlainText()             #普通文本获取

b.html标签文本设定,用法和普通文本一样。

QTextEdit.setHtml('str')
QTextEdit.insertHtml('str')
QTextEdit.toHtml()

c.还可以自动设置文本

QTextEdit.setText('str')

这个可以自动设置文本。

d.其余API

QTextEdit.append('str')     #文本追加(不管光标位置)
QTextEdit.clear()           #文本清除

文本追加时也是自动判定的,它不管光标的位置直接在文本后追加文本(另起一行)

三.文本光标

在上面的部分我们介绍了一种通过类提供的方法改变文本内容的方法,这里讲的是另一种:通过文本光标来操作文本框的内容。

首先来了解一下什么叫文本光标:通常我们在编辑文本文件时,是通过一个文本编辑器(就想word)操作的。word和文本文档在内存中建立了对应的关系,通过一个叫‘文本光标’的抽象的对象在内存中对文本文档进行操作。我们可以通过文本光标对QTextEdit进行各种操作。

获取光标,在获取光标后,就可以进行一系列的操作了。

te = QTextEdit(window)
tc = te.textCursor()      #获取光标

为了演示,我们建立一个界面,界面上一个按钮btn,一个QTextEdit,btn对应了一个槽函数fun,为了演示不同的效果,在下面的代码中值改变fun函数,先把大的框架放出来

 文本光标程序框架

1.插入文本

def fun():
    tc = te.textCursor()
    tcf = QTextCharFormat()    #定义插入的文本格式
    tcf.setFontFamily('隶属')  #定义格式字体
    tcf.setFontPointSize(30)   #定义格式字体大小
    tc.insertText('插入文本',tcf) #按格式插入字体
    tc.insertHtml("<a href='http://www.baidu.com'> 百度</a>")  #插入html文本(超链接)

如果想查看具体的格式设置,可以按下Ctrl键点击QTextCharFormat看看里面的构造函数,我们在后面还会再详细讲解。这里插入的超链接由于设置的关系不能用鼠标点击,但是已经有超链接的外观效果了。还有一种是插入文本片段

def fun():
    tc = te.textCursor()
    tdf = QTextDocumentFragment().fromPlainText('123')   #插入普通文本片段
    tc.insertFragment(tdf)
    tdf2 = QTextDocumentFragment.fromHtml("<a href='http://www.baidu.com'> 百度</a>") #插入html标签文本片段
    tc.insertFragment(tdf2)

2.插入图片

def fun():
    tc = te.textCursor()
    pic = QTextImageFormat()
    pic.setName('picture.png')   #图片路径
    pic.setHeight(50)            #图片高度
    pic.setWidth(50)             #图片宽度
    tc.insertImage(pic)          #插入图片

这里的picture.png是在同目录下一个图片。还有几个已经过期但还可用的API,可以了解一下

tc.insertImage(pic,QTextFrameFormat)          #按格式插入图片
tc.insertImage('picture.png')                 #直接按文件名插入图片

3.插入列表

还可以在QTextEdit里插入一个列表,在输入文字的时候可以有下面的效果

就像自动的段落编号一样,可以在每次换行的时候自动生成一个列表编号或样式。设置的API

def fun():
    tc = te.textCursor()
    tlf = QTextListFormat.ListCircle
    tc.insertList(QTextListFormat.ListCircle)   #插入列表,并把光标右边的字符置为列表第一项
    tc.insertList(tlf) #在当前位置插入一个新块,并使其成为具有给定格式的新创建列表的第一个列表项,返回创建的列表
    tc.createList(QTextListFormat.ListCircle)   #创建列表,并把光标所在行(段落)的字符置为列表第一项
    tc.createList(tlf)
#常用列表样式枚举值
    QTextListFormat.ListDisc       #圆点
    QTextListFormat.ListCircle     #空心圆
    QTextListFormat.ListSquare     #方块
    QTextListFormat.ListDecimal    #数字升序
    QTextListFormat.ListUpperRoman #大写罗马数字
    QTextListFormat.ListLowerRoman #小写罗马数字
    QTextListFormat.ListUpperAlpha #大写拉丁字母
    QTextListFormat.ListLowerAlpha #小写拉丁字母

除了上面的枚举值,还有另外一种设定方法

def fun():
    tc = te.textCursor()
    tlf = QTextListFormat()
    tlf.setIndent(3)                            #设定缩紧
    tlf.setNumberPrefix('<<')                  #如果列表值为数字,设定数字前缀
    tlf.setNumberSuffix('>>>')                 #如果列表值为数字,设定数字后缀
    tlf.setStyle(QTextListFormat.ListDecimal)  #样式设置
    t2 = tc.insertList(tlf)

出来就是这样的效果

4.插入表格

可以在文本块内插入表格

def fun():
    tc = te.textCursor()
    # tc.insertTable(10,5)      #直接插入表格(行,列)
    ttf = QTextTableFormat()    #创建表格对象格式
    tc.insertTable(10,5,ttf)    #按格式插入表格

下面是常用的格式定义

ttf = QTextTableFormat()                 #创建表格对象格式
ttf.setCellPadding(10)                   #单元格内文本和边框距离
ttf.setCellSpacing(20)                   #单元格线宽
ttf.setAlignment(Qt.AlignRight)          #对齐模式

 QTextTableFormat内容

 插入表格时,把插入的表格赋值给一个变量,还可以对这个表格进行一系列QTextTable里的各种操作,这里列举几个效果

def fun():
    tc = te.textCursor()
    ttf = QTextTableFormat()
    ttf.setCellPadding(10)
    table = tc.insertTable(3,2,ttf)
    table.appendColumns(3)      #追加列
    table.appendRows(2)         #追加行
    table.mergeCells(1,2,2,3)   #合并单元格(第1行第2列开始,合并2行3列)

下面是QTextTable里的各种功能。

 QTextTable功能

在使用表格时,常常需要对表格的列宽进行约束,先了解一下列宽约束的API

def setColumnWidthConstraints(self, constraints: typing.Iterable[QTextLength]) -> None: ...

可以看出来,函数传递参数的是一个可迭代的对象,并且定义了typing(QTextLength的构造函数标注了两种长度值:百分比(PercentageLength)和像素值(FixedLength))所以用起来是这样的

def fun():
    tc = te.textCursor()
    ttf = QTextTableFormat()
    # ttf.setColumnWidthConstraints((QTextLength(QTextLength.PercentageLength,60),QTextLength(QTextLength.PercentageLength,40))) #百分比定义列宽
    ttf.setColumnWidthConstraints((QTextLength(QTextLength.FixedLength,80),QTextLength(QTextLength.FixedLength,70)))             #像素定义列宽
    table = tc.insertTable(3,2,ttf)

5.插入文本块

这里说的文本块就是一个用回车键分隔的段落(block),是可以带有一定格式或样式的。插入文本块有这三种方法

insertBlock()                                #插入空文本块
insertBlock(QTextBlockFormat)                #插入文本块的同时设置文本块格式
insertBlock(QTextBlockFormat,QTextCharFormat)#插入文本块同时设置文本块格式和字符格式

注意的是第三种,要明白文本块格式和字符格式的区别:由于文本块是一个段落,就会有缩进、对齐方式、间距等,而单个的字符格式就是字体、颜色、背景色等等。

def fun():
    tc = te.textCursor()
    tbf = QTextBlockFormat()   #文本块格式
    tbf.setIndent(2)
    tcf = QTextCharFormat()    #字体格式
    tcf.setFontPointSize(20)
    tc.insertBlock(tbf,tcf)
    te.setFocus()

6.插入框架

在文本框内还可以插入一个框架,像下面的效果

在文本框内的框架里还可以输入字符,用法是这样的

def fun():
    tc = te.textCursor()
    tff = QTextFrameFormat()
    tff.setBorder(5)
    # tff.setBackground('cyan')
    tc.insertFrame(tff)

 用文本框架可以把一个大的框架分出多个小框架

def fun():
    tc = te.textCursor()
    tff = QTextFrameFormat()
    tff.setBorder(5)
    tff.setBorderBrush(QColor(50,50,50))
    tff.setRightMargin(30)

    doc = te.document()
    root_frame = doc.rootFrame()
    root_frame.setFrameFormat(tff)

    tc.insertFrame(tff)

出来的效果

可以给小的框架里放内容,还可以设置小框的样式。

7.光标选中

用代码实现光标的选中有个反向设置的概念

def fun():
    tc = te.textCursor()
    tc.setPosition(2,QTextCursor.KeepAnchor)
    te.setTextCursor(tc)                        #光标反向设置
    te.setFocus()

注意,这里先定义了光标,在把光标重新设置给QTextEdit控件。光标的移动有下面几种方法

a.方式1:指定移动到的位置

setPosition(self, pos: int, mode: 'QTextCursor.MoveMode' = ...)   
#移动模式
QTextCursor.KeepAnchor   #保持锚点(选中效果)
QTextCursor.MoveAnchor   #移动锚点(无选中效果)

只要指定好目标位置,光标可以直接移动到目标位置,移动模式决定了是否有选中的功能。

b.方式2:按效果移动光标

movePosition(self, op: 'QTextCursor.MoveOperation', mode: 'QTextCursor.MoveMode' = ..., n: int = ...)

 移动方式枚举值

 有些移动方式是可以加个量值的,例如Left,加个n就是向左移动n个字符。

c.方式3:直接选中(不用设置光标移动模式,直接有选中效果)

select(QTextCursor.Document)   #选中效果
#选中效果枚举值
QTextCursor.WordUnderCursor   # 当前光标下的单词
QTextCursor.LineUnderCursor   # 当前光标下的行
QTextCursor.BlockUnderCursor  # 当前光标下的段落
QTextCursor.Document          # 整个文档

 8.获得选中

a.选中内容 的获取

def fun():
    tc =te.textCursor()
    tc.selectedText()       #获取选中的文本(返回值为字符串)
    tc.selection()          #获取文本片段对象(返回值为QTextDocumentFragment,里面有各种功能)
    tc.selectedTableCells() #获取选中的表格(左上行,左上列,右下行,右下列)

这里要注意的是,

  1.选中的片段对象可以进行QTextDocumentFragment类里的多种操作(取值、判定是否为空)等等

  2选中的表格必须是多个表格(cells),如果只选中一个表格则返回值为(-1,-1,-1,-1)。

b.选中位置的获取

def fun():
    tc =te.textCursor()
    tc.selectionStart()    #获取选中起始位置
    tc.selectionEnd()      #获取选中结束位置

9.选中的取消和判定

a.选中的取消

选中的取消也是需要反向设定给TextCursor的

def fun():
    tc = te.textCursor()
    tc.clearSelection()    #取消选中
    te.setTextCursor(tc)   #反向设定
    te.setFocus()

为了体现效果,在设定完成后设置焦点。

b.选中的判定

def fun():
    tc = te.textCursor()
    tc.hasSelection()       #判定是否有选中,返回布尔量

c.选中的移除

通过代码可实现把选中的内容删除

def fun():
    tc = te.textCursor()
    tc.removeSelectedText()  #删除选中内容

10.删除效果

可以通过代码实现删除键(Backspace键或Delete键)的效果

def fun():
    tc = te.textCursor()
    tc.deleteChar()         #删除光标后内容(Delete键)
    tc.deletePreviousChar() #删除光标前内容(Backspace键)

如果删除时无选中内容就删除光标前/后内容,但如果有选中内容时删除选中内容。

11.光标位置

获取光标位置或对其位置进行判定

def fun():
    tc = te.textCursor()
    tc.columnNumber()
#枚举值
QTextCursor.atBlockStart()   #是否在段落起始
QTextCursor.atBlockEnd()     #是否在段落结尾
QTextCursor.atStart()        #是否在文档开始
QTextCursor.atEnd            #是否在文档结束
QTextCursor.position()       #获取光标在文档中位置——>int
QTextCursor.positionInBlock()#获取光标在段落中位置——>int
QTextCursor.columnNumber()   #获取光标在第几列——>int

 12.开始和结束编辑操作

在对文档进行编辑时时可以直接多步骤进行撤销和重做的,这就需要一个对整段操作做一个标记

def fun():
    tc = te.textCursor()
    tc.beginEditBlock()     #开始编辑
    tc.insertText('123')
    tc.insertBlock()
    tc.insertText('456')
    tc.insertBlock()
    tc.insertText('789')
    tc.insertBlock()
    tc.endEditBlock()       #结束编辑

这时候再进行撤销,就是撤销从开始编辑到结束编辑之间的过程。

四.直接设置文本框

在上一节我们是用文本光标对文本框进行操作,但是需要先建立文本光标。其实有些操作是可以直接通过文本框来实现的。

1.自动格式化

外观效果和文本光标的插入列表有些像

def fun():
    te.setAutoFormatting(QTextEdit.AutoBulletList)
#枚举值
QTextEdit.AutoNone
QTextEdit.AutoBulletList   
QTextEdit.AutoAll

现在只支持了AutoBulletList一种效果,就是在点击“*”键后自动弹出列表

2.换行模式

换行模式有两种,一种是不进行软换行,在文本长度超出控件后产生水平滚动条,另一种是超出显示范围后进行软换行

但是软换行还有一个点:保持单词的完整性,如果换行会破坏单词的完整,则在单词前进行换行

换行方式1:直接设置(因为默认的情况都是直接换行的,这里就放出来不换行的方式)

te.setLineWrapMode(QTextEdit.NoWrap)    #设置换行模式(不换行)

换行方式2:指定固定宽度,这种方式要结合QTextEdit.setLineWrapColumnOrWidth()来使用。这个代码可以是列数也可以是宽度,取决于上面的代码

te.setLineWrapMode(QTextEdit.FixedPixelWidth)    #按像素限制换行
te.setLineWrapMode(QTextEdit.FixedColumnWidth)   #按列数限制换行
te.setLineWrapColumnOrWidth(5)        

如果用像素限制的化下面的数值就要填像素值,而用列数限制了则下面的数值要填列数,上面的案例就是限制在5列。

换行方式3:保持单词的完整性:

由于有些时候进行软换行,单词可能会被截断,可以保持其完整性

te.setWordWrapMode(QTextOption.WordWrap)    #保持单词完整

 还可以对换行模式、单词换行模式进行获取

QTextEdit.lineWrapMode()   #获取换行模式
QTextEdit.wordWrapMode()   #获取单词换行模式

获取的值是int,可以查询QTextEdit.LineWrapMode和QtGui.QTextOption.WrapMode里面的内容,对返回值进行了定义。

3.覆盖模式

覆盖模式就是键盘上Insert的按键是一样的,可以在新增字符是切换插入和替换的效果

QTextEdit.setOverwriteMode(True)   #覆盖模式
QTextEdit.overwriteMode()          #获取是否位覆盖模式——>bool

4.光标设置

QTextEdit.setCursorWidth(int)   #设定光标宽度
QTextEdit.cursorWidth()         #获取光标宽度——>int
QTextEdit.cursorRect()          #获取光标区间——>QRect

 5.对齐设置

QTextEdit.setAlignment(Qt.AlignRight)
#对齐枚举值
Qt.AlignCenter
Qt.AlignLeft
Qt.AlignRight

 五.字体设置

通过代码,可以对文本框里的字体进行字体、样式、尺寸等效果的设置,有

1.设置字体

te = QTextEdit(window)
te.setFontFamily('仿宋')    #设置字体
te.fontFamily              #获取字体设置

在设置FontFamily的时候,有个小技巧,可以用QFontDialog.getFont()来查看可用的字体和字体能使用的效果

QFontDialog.getFont()  #显示字体对话框

2.字体样式

字体样式主要分为字体粗细和字体斜体(字体对话框内Style里的部分),粗细由枚举值新设定,而斜体则由布尔量设定

te = QTextEdit(window)
te.setFontWeight(QFont.Bold)    #设定粗细
te.fontWeight()                 #获取粗细——>int
te.setFontItalic(True)          #设定斜体
te.fontItalic()                 #获取是否设定为斜体

 粗细枚举值

 

这里有个问题,PyQt5的源代码里定义的是设定粗细给定的是个int的数据,但是不能用,需要给QFont里的枚举值

def setFontWeight(self, w: int) -> None: ...

3.字体尺寸

te = QTextEdit(window)
te.setFontPointSize(30)   #设定尺寸(float)
te.fontPointSize()        #获取尺寸——>float

4.字体效果

字体效果主要是下划线效果(在光标设置字体里还有其他的效果,但通过对话框直接操作只有下划线)

te = QTextEdit(window)
te.setFontUnderline(True)   #下划线
te.fontUnderline()          #获取是否启用下划线

 5.统一设置

可以用QFont()的功能来对字体进行统一设置

te = QTextEdit(window)
font=QFont()
font.setStrikeOut(True)
te.setCurrentFont(font)

可以看一下QFont的构造函数,提供了这样的用法

def __init__(self, family: str, pointSize: int = ..., weight: int = ..., italic: bool = ...) -> None: ...

就是说我们在生命font的时候可以直接把字体样式带进去

font=QFont('隶书',-1,10,True)

这样就是说字体是隶书,像素点用默认值,字体粗细为10,斜体使用。

6.字体颜色

字体颜色分字体的颜色和字体背景色

te = QTextEdit(window)
te.setTextBackgroundColor(QColor('green'))       #设定背景色
te.textBackgroundColor()                         #获取背景色对象——>QColor object
te.setTextColor(QColor('red'))                   #改变字体颜色
te.textColor()                                   #获取字体颜色

7.利用QTextCharFormat设置字体

我们在文本光标里使用了QTextCharFormat对字体进行设置。

te = QTextEdit(window)
tcf =QTextCharFormat()
tcf.setFontPointSize(30)
te.setCurrentCharFormat(tcf)

注意这里的设定使用的setCurrentCharFormat,和上面字体设置(setCurrentFont)是不太一样的。还有几个枚举值挺有用的,这里罗列一下

tcf =QTextCharFormat()
tcf.setFontCapitalization(QFont.SmallCaps)  #字母大小写设定
tcf.fontCapitalization()                    #获取字母大小写设置——>int
te.setCurrentCharFormat(tcf)
#大小写设定枚举值
QFont.MixedCase      # 常规
QFont.AllUppercase     # 所有字母大写
QFont.AllLowercase     # 所有字母小写
QFont.SmallCaps      # 小型化的大写字母
QFont.Capitalize     #首字母大写

还有

tcf.setFontOverline()      #上划线
tcf.setFontStrikeOut()     #中划线

等等,可以查看QTextCharFormat里的定义。但是用

te.setCurrentCharFormat(tcf)

是设置新的字体,还得意合并字体设置

tcf =QTextCharFormat()                
te.setCurrentCharFormat(tcf)
tcf2 = QTextCharFormat()
te.mergeCurrentCharFormat(tcf2)   #把tcf2里的字体设置追加进去

这样就是把tcf2里的设置追加给tcf。

8.常规操作

先是常规的复制粘贴等操作

te = QTextEdit()
te.copy()
te.paste()
te.canPaste()
te.setUndoRedoEnabled()
te.undo()
te.redo()
te.selectAll()

这就是字面的意思,就不备注了,还有一个是搜索,要拿出来单讲一下

te.find(str,options=)

查找是的选项有几个枚举值

QTextDocument.FindBackward          #从后向前查找
QTextDocument.FindCaseSensitively   #默认查找不区分大小写,使用该枚举值启用区分大小写查找
QTextDocument.FindWholeWords        #找完整的单词

这三个枚举值是不冲突的,可以用或运算符"|"连接使用。例如

te.find('abc',QTextDocument.FindWholeWords|QTextDocument.FindCaseSensitively|QTextDocument.FindBackward)

就是只能查找光标左边abc的单词,加入有个abcd或Abcd是不行的。

9.只读设置

te = QTextEdit(window)
te.setReadOnly(True)   #设置位只读模式
te.isReadOnly()        #获取是否位只读模式

要注意两点,1.这里的只读模式只是对用户是只读的,利用代码还是可以修改文本框的内容的。

      2.设置位只读模式后右键出来的菜单只有复制和全选了,其余粘贴啥的都没有了。

10.tab键设置

因为在界面里的控件可以通过tab键切换焦点,但是在文本框里有时候也是用得到tab键的,那会不会冲突啊?可以这么设定

window = MyWindow()
te = QTextEdit(window)
te.setTabChangesFocus(True)   #tab键切换焦点

tab键默认在文本框里是制表符的,上面的代码可以强制切换焦点。还可以设置制表符的距离像素值

te.setTabStopWidth(100)     #设置制表符的距离(像素)
te.tabStopWidth()           #获取制表符的距离——>int

11.滚动到锚点

可以在文本中设定一个锚点(Anchor)通过按钮连接函数实现直接跳转到这个点处。

 滚动到锚点

锚点的设置

<a name ="锚点名称"href='锚点内容'>xxx</a>

六.常用信号

1.文本内容发生改变时发射的信号

QTextEdit.textChanged()

2.选中文本内容发生改变时发射的信号

QTextEdit.selectionChanged()

3.光标位置发生改变时发射的信号

QTextEdit.cursorPositionChanged()

4.当前字符格式发生改变时发射的信号(带有参数)

QTextEdit.currentCharFormatChanged(QTextCharFormat) #参数QTextCharFormat

5.复制可用时(返回布尔量)

QTextEdit.copyAvailable(bool)

6.重做可用时(返回布尔量)

QTextEdit.redoAvailable(bool)

7.撤销可用时(返回布尔量)

QTextEdit.undoAvailable(bool)

七.利用事件实现打开超链接的效果

我们在上面实现了在文本框内插入超链接,可以不能打开,那怎么实现超链接的打开呢?

1.利用事件

2.利用锚点的特性

anchorAt(self, pos: QtCore.QPoint) -> str: ...

如果Point在锚点上会返回锚点对应的字符串。总之,代码就是这样的

 打开超链接

结束!

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐