【问题标题】:In Qt5/PyQt5 how do I restore exact visible area and cursor position of QTextEdit?在 Qt5/PyQt5 中,如何恢复 QTextEdit 的确切可见区域和光标位置?
【发布时间】:2021-05-29 13:23:58
【问题描述】:

这个问题之前已经被问过,但只是关于 光标位置 看起来..

我已经实现了某种基于QTextEdit 的自动加载更改文本编辑器。问题是:当我使用

应用新加载的文本时
self.my_editor.setPlainText(new_text)

光标会跳到0的位置,很不舒服。

当然,我不是唯一一个有这种感觉的人,所以人们已经问过他们如何在应用新文本后恢复光标,例如这里:https://www.qtcentre.org/threads/13933-Restoring-cursor-position-in-QTextEdit

但我找到的答案只涵盖了文本光标本身的位置。

例如此代码将保存光标、设置新文本并恢复光标:

c = self.my_editor.textCursor()
p = c.position()
self.my_editor.setPlainText(new_text)
c.setPosition(p)
self.my_editor.setTextCursor(c)

但现在编辑器实际上会滚动到位置0,然后再次向下滚动,以便能够在恢复的位置显示光标。所以在视觉上编辑器会跳来跳去(不过这仍然比失去光标要好)

有没有办法同时存储QTextEdit 实例的可视区域?当然,如果文本内容真的发生了变化,那么将视觉跳跃最小化几乎是微不足道的,但是如果文本在光标后面发生变化,难道不应该根本看不到任何跳跃吗?

【问题讨论】:

    标签: python pyqt5 qtextedit cursor-position


    【解决方案1】:

    假设内容总是几乎一样,你可以存储滚动条的值,然后在更新文本后设置:

            c = self.my_editor.textCursor()
            p = c.position()
            hPos = self.my_editor.horizontalScrollBar().value()
            vPos = self.my_editor.verticalScrollBar().value()
            self.my_editor.setPlainText(new_text)
            c.setPosition(p)
            self.my_editor.horizontalScrollBar().setValue(hPos)
            self.my_editor.verticalScrollBar().setValue(vPos)
            self.my_editor.setTextCursor(c)
    

    滚动条和光标重置的顺序取决于您的需要:如果光标可能在可见视口之外,您可能更愿意先设置光标,然后再恢复滚动条。 p>

    最后,如果内容可以改变很多,你应该使用基于滚动条最大值的比率:

            try:
                hBar = self.my_editor.horizontalScrollBar()
                hPos = hBar.value() / hBar.maximum()
            except ZeroDivisionError:
                hPos = 0
            try:
                vBar = self.my_editor.verticalScrollBar()
                vPos = vBar.value() / vBar.maximum()
            except ZeroDivisionError:
                vPos = 0
            self.my_editor.setPlainText(new_text)
            c.setPosition(p)
            self.my_editor.setTextCursor(c)
            hBar.setValue(hPos * hBar.maximum())
            vBar.setValue(vPos * vBar.maximum())
    

    注意:最大值必须动态使用,因为范围可能会随着文本的变化而变化。

    【讨论】:

    • 这样做感觉有点奇怪——也许是因为我希望有某种更直接可访问的状态。但它与直接方法一样好,并且单独用于详细的第二次阐述你的答案值得奖励:)
    • 好吧,考虑一下移动滚动条正是 Qt 本身“在引擎盖下”所做的事情。这就是移动光标时所做的事情,就像项目视图中的scrollTo 或图形视图中的ensureVisible 之类的函数一样。考虑到文档明确指出始终使用滚动条进行 any 视口翻译,所以不用担心,这是标准的常见行为。
    猜你喜欢
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 2023-03-15
    相关资源
    最近更新 更多