Qt5/PyQt5 如何恢复QTextEdit 的准确可见区域和光标位置?
In Qt5/PyQt5 how do I restore exact visible area and cursor position of QTextEdit?
之前有人问过这个问题,但似乎只是关于 光标位置..
我实现了某种基于 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
实例的可视区域?当然,如果文本内容真的发生了变化,那么最小化视觉跳跃几乎是微不足道的,但如果文本发生变化 behind ,难道不应该根本看不到跳跃吗?光标?
假设内容总是几乎一样,可以将滚动条的值存起来,更新文本后再设置:
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)
滚动条和光标重置的顺序取决于您的需要:如果光标可以在可见视口之外,您可能更愿意先设置光标然后恢复滚动条。
最后,如果内容可以变化很多,你应该使用基于滚动条最大值的比率:
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())
注意:最大值必须动态使用,因为文本更改时范围可能会更改。
之前有人问过这个问题,但似乎只是关于 光标位置..
我实现了某种基于 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
实例的可视区域?当然,如果文本内容真的发生了变化,那么最小化视觉跳跃几乎是微不足道的,但如果文本发生变化 behind ,难道不应该根本看不到跳跃吗?光标?
假设内容总是几乎一样,可以将滚动条的值存起来,更新文本后再设置:
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)
滚动条和光标重置的顺序取决于您的需要:如果光标可以在可见视口之外,您可能更愿意先设置光标然后恢复滚动条。
最后,如果内容可以变化很多,你应该使用基于滚动条最大值的比率:
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())
注意:最大值必须动态使用,因为文本更改时范围可能会更改。