文本光标
- 描述
- 通过一张图来了解一下文本光标
-
- 在程序中,文本文档类似于我们日常工作中的docx文档
- 文本编辑器类似于操作docx文档的word软件(直观可见)
- 文本编辑器对文本文档的操作(格式设置、字体设置等)最终都将保存在文本文档中
- 文本光标同样可以对文本文档进行操作,最终将操作结果保存在文本文档中
- 但是文本光标并不是可视化的,不能直观可见
- 文本光标操作文本文档之后,文本编辑器再加载文本文档,文本文档最后的效果就展示在了文本编辑器上
- 通过一张图来了解一下文本光标
- 步骤
- 1、获取文本光标:
te.textCursor()
返回QTextCursor
对象 - 2、通过文本光标编辑器操作文本文档
- 3、操作过的文本文档在QTextEdit编辑器中显示
- 1、获取文本光标:
QTextDocument 文本文档对象
- ** 描述**
- 保存带格式的文本文档
- 为样式化文本和各种类型的文档元素提供支持(框架、文本块、列表、表格、图像...)
- 是结构化富文本文档的容器
- 一个空的文档包含一个根框架,这个框架包含一个空的文本块
- 当需要进行文档结构导航时,有时候可以从根框架开始。
- 因为根框架提供了访问整个文档结构的能力
-
- 文本属性在字符级别和块级别定义
- 在字符级别可以指定字体、颜色和大小
- 在块级别可以指定更高一级的行为,例如文本流方向、对齐方式和背景色
- 继承结构图
-
QTextCursor 文本光标对象
- 常用功能
- 添加内容
- 插入文本
insertText(str) # 插入文本(普通文本) insertText(QString text, QTextCharFormat format) # 插入文本, 带格式 # 参数 QTextCharFormat # 针对于部分字符的格式描述(后面会详细讲) tcf.setToolTip("浮动提示信息") # 设置文本提示信息 tcf.setFontFamily("幼圆") # 设置字体系列 tcf.setFontPointSize(60) # 设置字体大小 insertHtml(html_str) # 插入HTML 字符串(直接添加的超链接并不能点击跳转,需要额外设置)
- 插入图片
insertImage(QTextImageFormat) # 通过QTextImageFormat插入图片 # 参数 QTextImageFormat tf.setName("xxx.png") # 图片名称(全路径) tf.setWidth(20) # 图片宽度 tf.setHeight(20) # 图片高度 insertImage(QTextImageFormat, QTextFrameFormat.Position) # 已过期,还能使用。通过QTextImageFormat插入图片,同时设置显示位置 # 参数 QTextFrameFormat.Position # 通过QTextFrameFormat类里面的枚举设置图片显示位置 insertImage(name_str) # 已过期,还能使用。直接通过图片名称(全路径)插入图片 insertImage(QImage, name_str=None) # 已过期, 还能可用
- 插入文本片段
insertFragment(QTextDocumentFragment ) # 参数 QTextDocumentFragment # 构建对象,其方法通过 对象名.方法名() 直接调用 fromHtml(html_str) # 将Html内容转换为文本片段对象 fromPlainText(str) # 将普通文本内容转换为文本片段对象
- 插入列表
insertList(QTextListFormat) -> QTextList # 在当前位置插入一个新块,并使其成为具有给定格式的新创建列表的第一个列表项。返回创建的列表 insertList(QTextListFormat.Style) -> QTextList # 在当前位置插入一个新块,并使其成为具有给定格式的新创建列表的第一个列表项。返回创建的列表 createList(QTextListFormat ) -> QTextList # 创建并返回具有给定格式的新列表,并使当前段落的光标位于第一个列表项中 createList(QTextListFormat.style ) -> QTextList # 创建并返回具有给定格式的新列表,并使当前段落的光标位于第一个列表项中 # 插入列表:跳行,并将光标后面的内容作为列表的第一项,光标前面的内容不会作为列表内容 # 创建列表:不跳行,将光标所在行的所有内容作为列表的第一项 # 补充 QTextListFormat(文本列表格式对象) setIndent(int) # 设置列表的缩进,几个Tab键 setNumberPrefix(str) # 设置列表样式的前缀(前提是要先设置列表样式setStyle) >1 xxxxxx setNumberSuffix(str) # 设置列表样式的后缀(前提是要先设置列表样式setStyle) 1. xxxxxx setStyle(QTextListFormat_Style) # 设置列表样式,每个条目左侧图标(通过QTextListFormat类里面的枚举设置) QTextListFormat.Style(文本列表格式枚举对象) QTextListFormat.ListDisc # 一个实心圆圈 QTextListFormat.ListCircle # 一个空的圆圈 QTextListFormat.ListSquare # 一个实心方块 QTextListFormat.ListDecimal # 十进制值按升序排列(阿拉伯数字) QTextListFormat.ListLowerAlpha # 小写拉丁字符按字母顺序排列 QTextListFormat.ListUpperAlpha # 大写拉丁字符按字母顺序排列 QTextListFormat.ListLowerRoman # 小写罗马数字(仅支持最多4999项) QTextListFormat.ListUpperRoman # 大写罗马数字(仅支持最多4999项)
-
- 插入表格
insertTable(int rows, int columns) -> QTextTable # 插入表格,返回文本表格对象QTextTable insertTable(int rows, int columns, QTextTableFormat) -> QTextTable # 插入表格的同时设置表格属性对象,返回文本表格对象QTextTable # 补充 QTextTableFormat(文本表格格式对象) setAlignment(self, Union, Qt_Alignment=None, Qt_AlignmentFlag=None) # 设置表格与文本编辑器中的对齐方式,而不是表格单元格中文本的对齐方式 setCellPadding(self, p_float) # 内边距,文本内容距离单元格边框的距离 setCellSpacing(self, p_float) # 外边距,单元格与单元格直接的距离 setColumnWidthConstraints(self, Iterable, QTextLength=None) # 设置列宽 # Iterable 可迭代对象,元组,分别设置每列宽度 # 示例:ttf.setColumnWidthConstraints((QTextLength(QTextLength.PercentageLength, 50),QTextLength(QTextLength.PercentageLength, 30),QTextLength(QTextLength.PercentageLength, 20))) # 设置表格三列的宽度,分别占表格宽度的:50%、30%、20% # QTextLength.PercentageLength:百分比 # QTextLength.FixedLength:设置像素宽度 QTextTable(文本表格对象) appendColumns(self, p_int) # 追加列数 appendRows(self, p_int) # 追加行数 cellAt(self, *__args) # 获取光标所在单元格对象 insertColumns(self, p_int, p_int_1) # 在第p_int列后面插入p_int_1列 insertRows(self, p_int, p_int_1) # 在第p_int行后面插入p_int_1行 mergeCells(self, *__args) # 合并单元格mergeCells(偏移行,偏移列,合并行数,合并列数) resize(self, p_int, p_int_1) # 设置表格行数和列数
-
- 插入文本块
insertBlock() # 插入一个空的文本块 insertBlock(QTextBlockFormat) # 插入文本块的同时, 设置文本块格式 insertBlock(QTextBlockFormat, QTextCharFormat ) # 插入文本块的同时, 设置文本块格式和文本字符格式 # 补充 QTextBlockFormat(文本块格式对象) setAlignment # 设置对齐方式 setTopMargin # 设置顶部边距 setBottomMargin # 设置底部边距 setLeftMargin # 设置左侧边距 setRightMargin # 设置右侧边距 setIndent # 设置缩进(左侧) setLineHeight # setHeadingLevel # QTextCharFormat(文本字符格式对象) setFontPointSize(20) # 设置字体大小 setFontFamily('华文行楷') # 设置字体 setToolTip(str) # 设置工具提示信息
- 插入框架
- 在QTextEdit中有一个根框架,在这个根框架中有一个文本块,光标就处于这个文本块中
- 通过文本光标插入文本框架,实际上是在这个根框架中再插入一个框架
- 在这个文本框架中还可以继续添加文本块等
insertFrame(QTextFrameFormat) -> QTextFrame # 插入框架,返回一个文本框架对象 # 补充 QTextFrameFormat setBorder(5) # 设置边框线宽 setBorderBrush(QColor(100, 20,20)) # 设置边框颜色 setMargin(10) # 设置框架四方边距 setTopMargin # 设置顶部边距 setBottomMargin # 设置底部边距 setLeftMargin # 设置左侧边距 setRightMargin # 设置右侧边距
- 插入文本
- 设置和合并格式
setBlockCharFormat(QTextCharFormat) # 设置要格式化的当前块(或选择中包含的所有块)的块char 格式 setBlockFormat(QTextBlockFormat) # 设置当前块的块格式(或选择中包含的所有块)以进行格式化 setCharFormat(QTextCharFormat) # 将光标的当前字符格式设置为给定格式。如果光标有选择,则给定格式应用于当前选择 mergeBlockCharFormat(QTextCharFormat) # 合并当前块的char格式 mergeBlockFormat(QTextBlockFormat) # 合并当前块的格式 mergeCharFormat(QTextCharFormat) # 合并当前字符格式
- 获取内容和格式相关
block() -> QTextBlock # 获取光标所在的文本块 blockFormat() -> QTextBlockFormat # 获取光标所在的文本块格式 blockCharFormat() -> QTextCharFormat # 获取光标所在的文本块字符格式 blockNumber() -> int # 获取光标所在的文本块编号,从0开始 charFormat() -> QTextCharFormat # 获取文本字符格式 currentFrame() -> QTextFrame # 获取当前所在的框架 currentList() -> QTextList # 获取当前所在的文本列表 currentTable() -> QTextTable # 获取当前的表格
- 文本选中和清除
- 选中
setPosition(int pos, QTextCursor.MoveMode=MoveAnchor) # 设置光标位置,需要反向设置回去 movePosition(QTextCursor.MoveOperation, QTextCursor.MoveMode=MoveAnchor, int n = 1) # 移动指定长度后, 参照移动选项和模式确定最终位置以及是否选中文本,需要反向设置 select(QTextCursor.SelectionType) # 需要反向设置 # 反向设置 # 通过te.textCursor()拿到文本光标,再通过setPosition()移动光标之后,看不到效果 # 需要te.setTextCursor(tc)方法,再将这个文本光标对象设置给文本编辑器 # 参数:文本光标移动模式 QTextCursor.MoveMode QTextCursor.MoveAnchor # 将锚点移动到与光标本身相同的位置(光标移动不选中效果)。 QTextCursor.KeepAnchor # 将锚固定在原处(选中效果)。 # 参数:移动的选项操作 QTextCursor.MoveOperation QTextCursor.NoMove # 将光标保持在原位 QTextCursor.Start # 移至文档的开头。 QTextCursor.StartOfLine # 移动到当前行的开头。 QTextCursor.StartOfBlock # 移动到当前块的开头。 QTextCursor.StartOfWord # 移动到当前单词的开头。 QTextCursor.PreviousBlock # 移动到上一个块的开头。 QTextCursor.PreviousCharacter # 移至上一个字符。 QTextCursor.PreviousWord # 移到上一个单词的开头。 QTextCursor.Up # 向上移动一行。 QTextCursor.Left # 向左移动一个字符。 QTextCursor.WordLeft # 向左移动一个单词。 QTextCursor.End # 移到文档的末尾。 QTextCursor.EndOfLine # 移动到当前行的末尾。 QTextCursor.EndOfWord # 移到当前单词的末尾。 QTextCursor.EndOfBlock # 移动到当前块的末尾。 QTextCursor.NextBlock # 移动到下一个块的开头。 QTextCursor.NextCharacter # 移动到下一个角色。 QTextCursor.NextWord # 转到下一个单词。 QTextCursor.Down # 向下移动一行。 QTextCursor.Right # 向右移动一个角色。 QTextCursor.WordRight # 向右移动一个单词。 QTextCursor.NextCell # 移动到当前表中下一个表格单元格的开头。 # 如果当前单元格是行中的最后一个单元格,则光标将移动到下一行中的第一个单元格。 QTextCursor.PreviousCell # 移动到当前表内的上一个表格单元格的开头。 # 如果当前单元格是行中的第一个单元格,则光标将移动到上一行中的最后一个单元格。 QTextCursor.NextRow # 移动到当前表中下一行的第一个新单元格。 QTextCursor.PreviousRow # 移动到当前表中上一行的最后一个单元格。 # 参数:选中类型 QTextCursor.SelectionType QTextCursor.Document # 选择整个文档。 QTextCursor.BlockUnderCursor # 选择当前光标下的文本块。 QTextCursor.LineUnderCursor # 选择当前光标下的文本行。 QTextCursor.WordUnderCursor # 选择当前光标下的单词。如果光标未定位在可选字符串中,则不选择任何文本。
- 获取选中内容
selectedText() -> str # 获取选中的文本内容 selection() -> QTextDocumentFragment # 获取选中的文档字符片段对象 selectedTableCells() -> (int firstRow, int numRows, int firstColumn, int numColumns) # 获取选中的表格单元格 # 返回值(选中第一行的行号, 选中了多少行, 选中的第一列的列号, 选中了几列),行号和列号均是从0开始
- 获取选中的位置
selectionStart() -> int # 获取选中开始位置 selectionEnd() -> int # 获取选中结束位置
- 取消选中和判定
clearSelection() # 取消文本的选中,需要反向设置 hasSelection() -> bool # 是否有选中文本
- 删除选中文本
removeSelectedText() # 删除选中的文本
- 选中
- 删除内容
deleteChar() # 如果没有选中文本, 删除文本光标后一个字符 # 如果有选中文本, 则删除选中文本 deletePreviousChar() # 如果没有选中文本, 删除文本光标前一个字符 # 如果有选中文本, 则删除选中文本
- 获取和判定光标的位置
atBlockEnd() # 是否在文本块末尾 atBlockStart() # 是否在文本块开始 atEnd() # 是否在文档末尾 atStart() # 是否在文档开始 columnNumber() -> int # 在第几列(0开始) position() # 光标位置 positionInBlock() # 在文本块中的位置(0开始)
- 开始和结束编辑标识
beginEditBlock() # 开始编辑文本块标识 endEditBlock() # 结束编辑文本块标识 # 多个单独操作放在开始编辑文本块标识和结束编辑文本块标识之间,可以做到统一撤销等操作
- 示例代码
- 示例一:通过文本光标添加内容
from PyQt5.Qt import * import sys class Windows(QWidget): def __init__(self): super().__init__() self.setWindowTitle('QTextEdit-文本光标') self.resize(980, 500) self.widget_list() def widget_list(self): self.add_widget() def add_widget(self): te1 = QTextEdit(self) te2 = QTextEdit(self) self.te = te1 self.te2 = te2 te1.resize(475,440) te2.resize(475,440) te1.move(10, 10) te2.move(te1.x() + te1.width() + 5, 10) te1.setPlaceholderText('填写你的内容') te1.setPlaceholderText('填写你的内容') te1.setText('插入列表:大家好,我是失心疯') te2.setText('创建列表:大家好,我是失心疯') btn = QPushButton(self) btn.move(te1.x(),te1.y() + te1.height()+5) btn.setText('插入') btn2 = QPushButton(self) btn2.move(te2.x(), te2.y() + te2.height() + 5) btn2.setText('插入行列') btn.clicked.connect(self.insert_content) btn2.clicked.connect(self.test) def test(self): # self.tab.insertRows(2, 3) # self.tab.mergeCells(2,2,1,2) pass def insert_content(self): # ****************通过文本光标插入框架****************** 开始 tc = self.te.textCursor() tff = QTextFrameFormat() tff.setBorder(5) tff.setBorderBrush(QColor(100, 20,20)) tff.setMargin(10) tc.insertFrame(tff) # 获取QTextEdit编辑器里面的文本文档对象 doc = self.te.document() # 获取文本文档对象的根框架,返回QTextFrame对象 # QTextFrame root_frame = doc.rootFrame() # setFrameFormat(QTextFrameFormat) 设置框架格式 root_frame.setFrameFormat(tff) # ****************通过文本光标插入框架****************** 结束 return None # ****************通过文本光标插入文本块****************** 开始 tc = self.te.textCursor() # 插入一个空的文本块 # tc.insertBlock() # 创建一个文本块格式对象 tbf = QTextBlockFormat() tbf.setAlignment(Qt.AlignRight) # 设置右对齐 tbf.setRightMargin(50) # 设置右侧边距 tbf.setIndent(3) # 设置左侧缩进为3个Tab # 创建一个文本字符格式对象 tcf = QTextCharFormat() tcf.setFontPointSize(20) tcf.setFontFamily('华文行楷') tcf.setToolTip() # 插入一个带文本块格式的文本块 # tc.insertBlock(tbf) # 插入一个带文本块格式和文本字符格式的文本块 tc.insertBlock(tbf, tcf) self.te.setFocus() # ****************通过文本光标插入文本块****************** 结束 return None # ****************通过文本光标插入表格****************** 开始 tc = self.te.textCursor() # 方法一:插入指定行列的表格QTextTable # tab = tc.insertTable(5, 5) # 方法二:插入指定行列的表格,并设置格式对象 ttf = QTextTableFormat() ttf.setWidth(self.te.width()) ttf.setHeight(self.te.height()) ttf.setColumnWidthConstraints((QTextLength(2, 30),QTextLength(2, 20),QTextLength(2, 20),QTextLength(2, 10),QTextLength(2, 20))) tab = tc.insertTable(5,5,ttf) self.tab = tab # tab.resize(20,50) # ****************通过文本光标插入表格****************** 结束 return None # ****************通过文本光标插入列表****************** 开始 tc = self.te.textCursor() tc2 = self.te2.textCursor() # 方式一:通过QTextListFormat.Style 枚举样式设置列表 # 插入列表 # tc.insertList(QTextListFormat.ListDecimal) # 列表左侧图标为阿拉伯数字 # tc.insertList(QTextListFormat.ListDisc) # 一个实心圆圈 # tc.insertList(QTextListFormat.ListCircle) # 一个空心圆圈 # tc.insertList(QTextListFormat.ListSquare) # 一个实心方块 # tc.insertList(QTextListFormat.ListLowerAlpha) # 小写拉丁字符按字母顺序排列 # tc.insertList(QTextListFormat.ListUpperAlpha) # 大写拉丁字符按字母顺序排列 # tc.insertList(QTextListFormat.ListLowerRoman) # 小写罗马数字(仅支持最多4999项) # tc.insertList(QTextListFormat.ListUpperRoman) # 大写罗马数字(仅支持最多4999项) # 创建列表 # tc2.createList(QTextListFormat.ListDisc) # 方式二:通过QTextListFormat对象设置列表 # 1、创建QTextListFormat列表样式对象 tlf = QTextListFormat() # 2、设置列表的属性 tlf.setIndent(2) # 设置列表的缩进,几个Tab键 tlf.setNumberPrefix('> ') # 设置列表图标的前缀,必须设置列表图标的样式 tlf.setNumberSuffix(' < ') # 设置列表图标的后缀,必须设置列表图标的样式 tlf.setStyle(QTextListFormat.ListDecimal) # 设置列表图标的样式 tc.insertList(tlf) # 插入列表 tc2.createList(tlf) # 创建列表 # ****************通过文本光标插入列表****************** 结束 return None # ****************通过光标插入文本片段****************** 开始 tc = self.te.textCursor() tdf = QTextDocumentFragment() test1 = tdf.fromHtml("<H1>一级标题</H1>") test2 = tdf.fromPlainText("\n") test3 = tdf.fromPlainText("<H2>二级标题</H2>") tc.insertFragment(test1) tc.insertFragment(test2) tc.insertFragment(test3) # ****************通过光标插入文本片段****************** 结束 return None # ****************通过文本光标插入图片****************** 开始 tc = self.te.textCursor() img = QTextImageFormat() img.setName('../images/jpg/1.jpg') img.setWidth(self.te.width()) img.setHeight(self.te.height()) tc.insertImage(img) # ****************通过文本光标插入图片****************** 结束 return None # ****************通过文本光标插入Html****************** 开始 tc = self.te.textCursor() tc.insertHtml("<a href='https://www.baidu.com'>百度一下,你就知道</a>") # ****************通过文本光标插入Html****************** 结束 return None # ****************通过文本光标插入文本****************** 开始 # 获取文本光标对象,返回QTextCursor对象 tc = self.te.textCursor() # 方法一:通过文本光标直接插入文本内容 # tc.insertText('我是失心疯,喜欢完Python') # 方法二:通过文本光标插入文本内容的同时设置文本格式 # 创建文本格式对象 tcf = QTextCharFormat() # 设置文本格式 tcf.setToolTip('这是工具提示信息') tcf.setFontPointSize(20) tcf.setFontFamily('微软雅黑') # 添加文本内容的同时设置文本格式 tc.insertText('我是失心疯,我喜欢Python', tcf) # ***************通过文本光标插入文本******************* 结束 if __name__ == '__main__': app = QApplication(sys.argv) window = Windows() window.show() sys.exit(app.exec_())