参考博客
Qt开发技术:Qt富文本(二)Qt文本光标操作、文档布局、富文本编辑、处理和Demo_长沙红胖子Qt的技术博客_51CTO博客
QTextEdit中跳转到指定行_Funny-Boy的博客-CSDN博客_qtextedit 移动到指定行
qt中文本光标的使用__kirakira_的博客-CSDN博客_qt 输入光标
基本原理
由于没有直接跳转到指定行的api,需要先通过QTextDocument()内置的findBlockByLineNumber()来实现 “根据指定行号定位到该行的起点位于整个文本的第几个字符”,简单来说就是告诉它行号,它返回这个行的起始字符是整个文本的第几个字符。
这样我们就可以得到 指定范围的起始字符和结束字符
接着,利用文本光标,跳转到起始字符,并拖动光标至结束字符,实现指定行的选中;
最后,通过QTextCharFormat()将选中的文本转换为我们预设的格式。
收尾工作:取消选中,跳转到结束字符。
核心函数
def jump_and_highlight(browser=QTextBrowser, startLine=0, endLine=0):
# 预设字符格式
fmt = QTextCharFormat()
fmt.setFontWeight(QFont.Bold)
fmt.setForeground(Qt.darkMagenta)
# 将文本导入doc
doc = QTextDocument()
doc.setPlainText(browser.toPlainText())
# 通过doc获取起始字符和结束字符
start_pos = doc.findBlockByLineNumber(startLine-1).position()
end_pos = doc.findBlockByLineNumber(endLine).position()
# 文本光标选中
tc = browser.textCursor() # 获得文本光标
tc.setPosition(start_pos, QTextCursor.MoveAnchor) # 直接跳转到start_pos
tc.setPosition(end_pos-1, QTextCursor.KeepAnchor) # 保持选中,并移动到end_pos-1
tc.mergeCharFormat(fmt) # 格式化选中文本
tc.clearSelection() # 取消选中
tc.setPosition(end_pos-1, QTextCursor.MoveAnchor) # 直接跳转到end_pos-1
browser.setTextCursor(tc) # 设置文本光标
完整代码如下
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from sys import argv
text = """1 a\n2 b\n3 c\n4 d\n5 e\n6 f\n7 g\n8 h\n9 i
10 j\n11 k\n12 l\n13 m\n14 n\n15 o\n16 p\n17 q\n18 r\n"""
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(300, 250)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.formLayout = QFormLayout(self.centralwidget)
self.formLayout.setObjectName(u"formLayout")
self.textBrowser = QTextBrowser(self.centralwidget)
self.textBrowser.setObjectName(u"textBrowser")
self.textBrowser.setLineWrapMode(QTextEdit.NoWrap)
self.textBrowser.setReadOnly(False)
font = QFont()
font.setFamily(u"Arial")
font.setPointSize(22)
self.textBrowser.setFont(font)
self.formLayout.setWidget(0, QFormLayout.SpanningRole, self.textBrowser)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
self.textBrowser.setText(text)
# retranslateUi
def jump_and_highlight(browser=QTextBrowser, startLine=0, endLine=0):
# 预设字符格式
fmt = QTextCharFormat()
fmt.setFontWeight(QFont.Bold)
fmt.setForeground(Qt.darkMagenta)
# 将文本导入doc
doc = QTextDocument()
doc.setPlainText(browser.toPlainText())
# 通过doc获取起始字符和结束字符
start_pos = doc.findBlockByLineNumber(startLine-1).position()
end_pos = doc.findBlockByLineNumber(endLine).position()
# 文本光标选中
tc = browser.textCursor() # 获得文本光标
tc.setPosition(start_pos, QTextCursor.MoveAnchor) # 直接跳转到start_pos
tc.setPosition(end_pos-1, QTextCursor.KeepAnchor) # 保持选中,并移动到end_pos-1
tc.mergeCharFormat(fmt) # 格式化选中文本
tc.clearSelection() # 取消选中
tc.setPosition(end_pos-1, QTextCursor.MoveAnchor) # 直接跳转到end_pos-1
browser.setTextCursor(tc) # 设置文本光标
if __name__ == "__main__":
app = QApplication(argv) # 创建应用程序
mainWindow = QMainWindow() # 创建窗口
ui = Ui_MainWindow()
ui.setupUi(mainWindow)
jump_and_highlight(ui.textBrowser, 9, 10)
mainWindow.show() # 显示窗口
exit(app.exec_()) # 运行程序直到关闭
效果展示
不执行函数jump_and_highlight(ui.textBrowser, 9, 10),直接运行代码结果如下
执行函数jump_and_highlight(ui.textBrowser, 9, 10),运行代码结果如下,实现了跳转到9-10行,并将其高亮显示