在Python中,QPlainTextEdit的光标定位没有按预期工作
我正在用Python结合PyQ编写一个简单的应用。代码中使用 QPlainTextEdit,但在光标位置上遇到了一些问题。如果我只插入新文本,所有内容似乎都附在文本末尾。但我尝试移动光标时,得到了一些意外的结果。
self.result_text = QPlainTextEdit()
self.cursor = self.result_text.textCursor()
self.result_text.toPlainText()
''
self.result_text.insertPlainText('1\n')
self.result_text.toPlainText()
'1\n'
self.result_text.insertPlainText('2\n')
self.result_text.toPlainText()
'1\n2\n'
self.result_text.moveCursor(self.cursor.atEnd())
self.result_text.insertPlainText('3\n')
self.result_text.toPlainText()
'3\n1\n2\n'
现在的结果似乎是在文本开头插入,尽管我把光标位置设置在末尾。
self.result_text.moveCursor(self.cursor.atStart())
self.result_text.insertPlainText('4\n')
self.result_text.toPlainText()
'3\n4\n1\n2\n'
如果把光标位置设在起始位置,它会把新文本追加在之前的文本之后!如果持续插入文本,它会在前一个文本之后追加。
self.result_text.insertPlainText(' 5 ')
self.result_text.toPlainText()
'3\n4\n 5 1\n2\n'
self.result_text.insertPlainText(' 6 ')
self.result_text.toPlainText()
'3\n4\n 5 6 1\n2\n'
self.cursor.position()
14
len(self.result_text.toPlainText())
14
文本的长度似乎也与光标位置一致。
我肯定是漏掉了什么,但完全不知道自己错在何处。
---------------------- 编辑 -----------------------
我添加了一个最小可复现的示例
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPlainTextEdit
from PyQt5.QtGui import QTextCursor
from PyQt5.QtCore import PYQT_VERSION_STR, QT_VERSION_STR
print("PyQt:", PYQT_VERSION_STR)
print("Qt:", QT_VERSION_STR)
class Window(QWidget):
def __init__(self):
super().__init__()
self.result_text = QPlainTextEdit()
self.result_text.setPlainText("Initial text")
self.cursor = self.result_text.textCursor()
text = self.result_text.toPlainText()
print('Initial text: {}'.format(text))
layout = QVBoxLayout()
layout.addWidget(self.result_text)
self.setLayout(layout)
self.result_text.insertPlainText("1\n")
print(self.result_text.toPlainText())
self.result_text.moveCursor(self.cursor.atEnd())
self.result_text.insertPlainText("2\n")
print(self.result_text.toPlainText())
self.result_text.moveCursor(self.cursor.atStart())
self.result_text.insertPlainText("3\n")
print(self.result_text.toPlainText())
self.result_text.insertPlainText("4\n")
print(self.result_text.toPlainText())
app = QApplication(sys.argv)
window = Window()
window.show()
app.exec()
解决方案
当我尝试使用
self.result_text.moveCursor(self.cursor.atEnd())
self.result_text.moveCursor(self.cursor.atStart())
时会抛出错误,因为 atEnd() 和 atStart() 给出的值是 True/False,但函数 moveCursor() 期望的是不同的东西。
TypeError: moveCursor(self, operation: QTextCursor.MoveOperation, mode: QTextCursor.MoveMode = QTextCursor.MoveAnchor):
argument 1 has unexpected type 'bool'
文档:atEnd()
当光标在文档末尾时返回true;否则返回false。
文档:atStart()
当光标在文档开头时返回true;否则返回false。
正确的用法是(使用 QTextCursor.MoveOperation)
from PyQt6.QtGui import QTextCursor
self.result_text.moveCursor(QTextCursor.MoveOperation.End)
self.result_text.moveCursor(QTextCursor.MoveOperation.Start)
在基于Ubuntu 24.04的 Linux Mint 22上测试,Python 3.13,PyQt 6.11。
用于测试的完整可运行代码:
import sys
from PyQt6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPlainTextEdit
from PyQt6.QtGui import QTextCursor
from PyQt6.QtCore import PYQT_VERSION_STR, QT_VERSION_STR
print("PyQt:", PYQT_VERSION_STR)
print("Qt:", QT_VERSION_STR)
class Window(QWidget):
def __init__(self):
super().__init__()
self.result_text = QPlainTextEdit()
# self.result_text.setPlainText("Hello world")
self.cursor = self.result_text.textCursor()
text = self.result_text.toPlainText()
print(text)
self.test()
layout = QVBoxLayout()
layout.addWidget(self.result_text)
self.setLayout(layout)
def test(self):
self.result_text = QPlainTextEdit()
self.cursor = self.result_text.textCursor()
print(self.result_text.toPlainText())
print("---")
self.result_text.insertPlainText("1\n")
print(self.result_text.toPlainText())
print("---")
# '1\n'
self.result_text.insertPlainText("2\n")
print(self.result_text.toPlainText())
print("---")
# '1\n2\n'
# self.result_text.moveCursor(self.cursor.atEnd()) # it raises Error
self.result_text.moveCursor(QTextCursor.MoveOperation.End) # it works
# self.cursor.movePosition(QTextCursor.MoveOperation.End) # it needs `setTextCursor()` to work
# self.result_text.setTextCursor(self.cursor)
self.result_text.insertPlainText("3\n")
print(self.result_text.toPlainText())
print("---")
# '3\n1\n2\n'
# Now the result seem to enter the text at the start although I set the cursor position at the end.
# self.result_text.moveCursor(self.cursor.atStart()) # it raises Error
self.result_text.moveCursor(QTextCursor.MoveOperation.Start) # it works
# self.cursor.movePosition(QTextCursor.MoveOperation.Start) # it needs `setTextCursor()` to work
# self.result_text.setTextCursor(self.cursor)
self.result_text.insertPlainText("4\n")
print(self.result_text.toPlainText())
print("---")
# '3\n4\n1\n2\n'
# If I set the cursor position at the start it append the new text after the previous one! If I keep inserting text it is appended after the previous one.
self.result_text.insertPlainText(" 5 ")
print(self.result_text.toPlainText())
print("---")
# '3\n4\n 5 1\n2\n'
self.result_text.insertPlainText(" 6 ")
print(self.result_text.toPlainText())
print("---")
# '3\n4\n 5 6 1\n2\n'
print("position:", self.cursor.position())
# 14
print("len:", len(self.result_text.toPlainText()))
# --- main ---
app = QApplication(sys.argv)
window = Window()
window.show()
app.exec()
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。