在Python中,QPlainTextEdit的光标定位没有按预期工作

编程语言 2026-07-09

我正在用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()

文档:QPlainTextEdit.moveCursor()QTextCursor.MoveOperation

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章