首页 > 技术文章 > PyQt5 基本语法(三):文本光标

liuzhongkun 2022-03-30 20:18 原文

文本光标

1、 理论基础

  • 通过文本光标,可以操作编辑文本文档对象
  • 概念:
    • 整个文本编辑器,其实就是为编辑这个文本文档,提供了一个可视化的界面
    • 简单理解,可以比喻成一个doc文档,使用word软件打开了这个文档,就可以随意修改文档内容
  • 获取文本文档的方法:
    • document():得到QTextDocument

textCursor()

2、 内容相关

2.1 添加内容

2.1.1 插入文本

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys


app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
tx = QTextEdit(w)
tx.resize(500, 500)

# 使用文本光标设置样式
text_cursor = tx.textCursor()  # 获取文本光标对象

text_cursor.insertHtml("<h1>这是一级标题<h2>")  # 插入富文本
text_cursor.insertText("这是普通文本内容")  # 插入普通文本内容

format_ = QTextCharFormat()  # 创建一个文本格式
format_.setToolTip("你好呀,你看到这句话,就说明语法没关系")
format_.setFont(QFont("隶书"))  # 设置文本字体为隶书
text_cursor.insertText("格式化文本", format_)  # 设置文本的格式

w.show()
sys.exit(app.exec_())

2.1.2 插入图片

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys


app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
tx = QTextEdit(w)
tx.resize(500, 500)

text_cursor = tx.textCursor()  # 获取文本光标对象
format_ = QTextImageFormat()  # 创建一个图片格式
format_.setName("./open.jpg")  # 设置图片
format_.setHeight(100)  # 设置图片高度
format_.setWidth(100)  # 设置图片宽度
text_cursor.insertImage(format_)  # 添加图片,推荐,其他创建方式可以到源代码中查看

w.show()
sys.exit(app.exec_())

2.1.3 插入句子

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys


app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
tx = QTextEdit(w)
tx.resize(500, 500)

text_cursor = tx.textCursor()
qtd = QTextDocumentFragment.fromHtml("<h1>xxx</h1>")  # 插入 HTML 文本
text_cursor.insertFragment(qtd)

w.show()
sys.exit(app.exec_())

2.1.4 插入列表

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys


app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
tx = QTextEdit(w)
tx.resize(500, 500)

text_cursor = tx.textCursor()

# text_cursor.insertList(QTextListFormat.ListDisc)  # 插入列表,里面传入列表的样式
# text_cursor.createList(QTextListFormat.ListDisc)  # 创建列表,里面传入列表的样式

format_ = QTextListFormat()
format_.setIndent(4)  # 设置缩进
format_.setNumberPrefix("<<")  # 设置列表前面图标的前缀
format_.setNumberSuffix(">>")  # 设置图标的后缀
format_.setStyle(QTextListFormat.ListDecimal)  # 设置图标样式
text_cursor.insertList(format_)  # 指定格式插入列表

w.show()
sys.exit(app.exec_())

QtextListFormat.Style:定义左侧显示的图标

  • QTextListFormat.ListDisc:圆圈
  • QTextListFormat.ListCircle:空圆圈
  • QTextListFormat.ListSquare:方块
  • QTextListFormat.ListDecimal:十进制值按照升序排列
  • QTextListFormat.ListLowerAlpha:小写拉丁字符按字母顺序排列
  • QTextListFormat.ListUpperAlpha:大写拉丁字符按字母顺序排列
  • QTextListFormat.ListLowerRoman:小写罗马数字
  • QTextListFormat.ListUpperRoman:大写罗马数字

2.1.5 插入表格

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys

app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
tx = QTextEdit(w)
tx.resize(500, 500)

text_cursor = tx.textCursor()

format_ = QTextTableFormat()
format_.setAlignment(Qt.AlignRight)  # 列表向右对齐
format_.setCellPadding(6)  # 设置内边距
format_.setCellSpacing(0)  # 设置外边距
format_.setColumnWidthConstraints([QTextLength(QTextLength.PercentageLength, 4), QTextLength(QTextLength.PercentageLength, 6)])# 设置列宽约束,约束第一列列宽为 4 ,第二列列宽为 6
# text_cursor.insertTable(3, 2)  # 创建一个三行二列的表格
table = text_cursor.insertTable(3, 2, format_)  # 创建一个三行二列的表格,并且设置格式
table.appendRows(3)  # 追加三行
table.insertRows(0, 3)  # 在首行插入三行

w.show()
sys.exit(app.exec_())

2.1.6 插入文本块

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys

app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
tx = QTextEdit(w)
tx.resize(500, 500)
tx.setFocus()

text_cursor = tx.textCursor()
format_ = QTextBlockFormat()
format_.setIndent(2)  # 设置缩进
format_.setAlignment(Qt.AlignLeft)  # 设置为右对齐
format_.setTopMargin(100)  # 设置文本块离顶层的外边距
text_cursor.insertBlock(format_)  # 插入一个文本块,后面还可以添加文本字符格式

w.show()
sys.exit(app.exec_())

2.1.7 插入框架

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys

app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
tx = QTextEdit(w)
tx.resize(500, 500)
tx.setFocus()

text_cursor = tx.textCursor()
format_ = QTextFrameFormat()    
format_.setBorder(10)  # 设置边框
format_.setBorderBrush(QColor("red"))  # 设置颜色
text_cursor.insertFrame(format_)  # 创建一个文本框架

w.show()
sys.exit(app.exec_())

2.2 设置和合并格式

text_cursor.setBlockCharFormat(QTextCharFormat)  # 设置要格式化的当前块,或选中包含的所有块 的块 char 格式
setBlockFormat(QTextBlockFormat)  # 设置当前的块格式,或选中包含的所有块,进行格式化
setCharFormat(QTextCharFormat)  # 将光标当前字符格式设置为指定格式;如果光标有选择,则将选择内容设置为指定格式
mergeBlockCharFormat(QTextBlockCharFormat)  # 合并当前块的char格式
mergeBlockFormat(QTextBlockFormat)  # 合并当前块的格式
mergeCharFormat(QTextCharFormat)  # 合并当前字符格式

合并的效果是叠加的

2.3 获取内容和格式

block()  # 获取光标所在的文本块
block().text()  # 获取光标的文本内容
blockFormat()  # 获取光标所在的文本块格式
blockCharFormat()  # 获取光标所在文本块的字符格式
blockNumber()  # 获取光标所在文本块的编号
charFormat()  # 获取文本字符格式
currentFrame()  # 获取当前所在的框架
currentList()  # 获取当前所在的文本列表
currentTable()  # 获取当前所在的表格

2.4 文本选中和清空

2.4.1 光标选中

setPositon(int pos, QTextCursor.MoveMode=MoveAnchor)  # 设置光标位置,反向设置
movePosition(QTextCursor.MoveOperation, QTextCursor.MoveMode=MoveAnchor, int n = 1)  # 反向设置
select(QTextCursor.SelectionType)  # 反向设置

QTextCursor.MoveMode:

  • QTextCursor.MoveAnchor : 将锚点移动到与光标本身相同的位置
  • QTextCursor.KeepAnchor: 将锚点固定值哎原来的位置

QTextCursor.MoveOperation: 内容比较多,请到官方文档查看

QTextCursor.SelectionType:

  • QTextCursor.Document : 选择整个文档
  • QTextCursor.BlockUnderCursor:选择光标下的文本块
  • QTextCursor.LineUnderCursor:选择光标下的文本行
  • QTextCursor.WordUnderCursor:选择光标下的单词
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys

app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
tx = QTextEdit(w)
tx.resize(500, 400)


def btn_():
    text_cursor = tx.textCursor()
    # text_cursor.setPosition(6, QTextCursor.MoveAnchor)  # 将光标移动到6的位置,设置锚点位置,锚点跟随移动
    # text_cursor.movePosition(QTextCursor.Up, QTextCursor.KeepAnchor, 2)  # 光标向上移动2行,锚点不跟随移动
    text_cursor.select(QTextCursor.LineUnderCursor)
    tx.setTextCursor(text_cursor)  # 需要把文本光标对象设置回给文本,这叫反向设置
    tx.setFocus()

    
btn = QPushButton("test", w)
btn.pressed.connect(btn_)
btn.move(203, 410)

w.show()
sys.exit(app.exec_())

2.4.2 选中内容获取

selectText()  # return str
selectionStart()  # 获取开始位置的索引
selectionEnd()  # 获取结束位置的索引
selection()  # return QTextDocumentFragment
selectedTableCells()  # return (int first_row_index, int rows_count, int first_col_index, int col_count)

示例:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys

app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
tx = QTextEdit(w)
tx.resize(500, 400)

tx.textCursor().insertTable(5, 3)  # 创建表格

def btn_():
    text_cursor = tx.textCursor()
    print(text_cursor.selectedText())  # 返回字符串
    print(text_cursor.selectionStart())
    print(text_cursor.selectionEnd())
    print(text_cursor.selection().toPlainText())  # QTextDocumentFragment,输出普通文本文档
    print(text_cursor.selectedTableCells())  # return (int first_row_index, int rows_count, int first_col_index, int col_count)



btn = QPushButton("test", w)
btn.pressed.connect(btn_)
btn.move(203, 410)

w.show()
sys.exit(app.exec_())

2.4.3 选定内容删除和判定

clearSelection()  # 取消选中的内容,其要反向设置
hasSelection()  # 判断有没有选中内容
removeSelection()  # 移除选定的内容,不需要反向设置

deleteChar()  # 如果没有选中文本,删除文本光标后一个字符;选中文本,则删除选中内内容
deletePreviousChar()  # 如果没有选中文本,删除文本光标前一个字符;选中文本,则删除选中内容

2.5 位置相关

atBlockEnd()  # 是否在文本块的末尾
atBlockStart()  # 是否在文本块的开始
atEnd()  # 是否在文档末尾
atStart()  # 是否在文档开头

columnNumber()  # 返回在第几列
position()  # 返回光标在文档位置
positionBlock()  # 返回在文本块中的位置

2.6 开始和结束编辑标识

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# @author: kun
from PyQt5.Qt import *
import sys

app = QApplication(sys.argv)
w = QWidget()
w.resize(500, 500)
tx = QTextEdit(w)
tx.resize(500, 400)


def btn_():
    text_cursor = tx.textCursor()
    text_cursor.beginEditBlock()  # 开始插入文本内容
    text_cursor.insertText("hello")
    text_cursor.insertText("world")
    text_cursor.endEditBlock()  # 结束插入文本内容


btn = QPushButton("test", w)
btn.pressed.connect(btn_)
btn.move(203, 410)

w.show()
sys.exit(app.exec_())

通过这个方法,可以将多个内容输入合并为一个输入,方便对内容的后续操作

推荐阅读