阻止QTextCursor :: insertText()修改QTextDocument滚动条范围

时间:2018-07-24 13:36:37

标签: c++ qt qtextedit qtextdocument qtextcursor

我有一个QTextEdit,其中包含一个QTextDocument,正在使用QTextCursor界面对其进行编程编辑。正在使用QTextCursor::insertText()编辑文档。

我加载了要分块编辑的文本文件,因此QTextDocument的初始大小可能仅为20行,即使文档为100,000行。但是,我希望QTextEdit滚动条能够反映文档的完整大小,而不只是当前显示的20行文档。

QTextEdit的滚动条范围设置为QScrollBar::setMaximum(),它在文件的初始打开时将滚动条调整为适当的大小,但是当调用QTextCursor::insertText()时,QScrollBar的范围是重新计算。

我已经尝试过在每个QScrollBar::setMaximum()事件之后调用QTextCursor::insertText(),但这只会使整个UI变得混乱而草率。

在修改QScrollBar时,有什么方法可以保持QTextDocument的范围吗?

2 个答案:

答案 0 :(得分:0)

是的。您将依赖于实现细节。在QTextEditPrivate::init()中,建立以下连接:

Q_Q(QTextEdit);
control = new QTextEditControl(q);
...
QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), q, SLOT(_q_adjustScrollbars()))

此处,q的类型为QTextEdit*,是API对象的Q-pointer。因此,您需要断开此连接,并自行管理滚动条:

bool isBaseOf(const QByteArray &className, const QMetaObject *mo) {
  while (mo) {
    if (mo->className() == className)
      return true;
    mo = mo->superClass();
  }
  return false;
}

bool setScrollbarAdjustmentsEnabled(QTextEdit *ed, bool enable) {
  QObject *control = {};
  for (auto *ctl : ed->children()) {
    if (isBaseOf("QWidgetTextControl", ctl->metaObject()) {
      Q_ASSERT(!control);
      control = ctl;
    }
  }
  if (!control)
    return false;
  if (enable)
    return QObject::connect(control, SIGNAL(documentSizeChanged(QSizeF)), ed, SLOT(_q_adjustScrollbars()), Qt::UniqueConnection);
  else
    return QObject::disconnect(control, SIGNAL(documentSizeChanged(QSizeF)), ed, SLOT(_q_adjustScrollbars()));
}

希望这足以防止QTextEdit干扰您。

答案 1 :(得分:0)

我正在将qt用于python,但我认为地下环境是相同的。

  1. 您确定可变的页面大小。(A4 =宽度= 797,高度= 1023)
  2. 您插入文本。
  3. 如果您插入Text,则textcursor是文档的最底行。
  4. 你得到了直肠。
  5. 您按页面大小指定矩形。
  6. 如果文本长度20行等于1页,则20行是一页的最后一页。如果将高度设置为1023,则此页面的底部高度可能是1023。current_bottomline + cursor.height> 1023 * pageheight = current_page last_bottomline + cursor.height> 1023 * lastpageheiht = max_page
  7. 您调整文本的大小。(797,1023 *页面)
  8. 如果您使用Backspace键或Delete键删除文本,则必须重新计算最后一行。(我建议在KeyEvent中进行此检查。)QTextCursor.movePosition(QtGui.QTextCursor.End,QtGui.QTextCursor.MoveAnchor,1)

  9. 然后,您得到cursorRect()

  10. 您将高度除以A4大小单位高度。
  11. 如果高度为102300,则页面将为100。
  12. 将页面大小设置为100。
  13. 您调整textedit的大小调整大小(797,1023 * page)
  14. 您可以获得textedit.verticalScrollBar()
  15. 您设置了verticalScrollBar()setMaximum(最后一页的高度)
  16. 您可以通过setSliderPosition(相同的值或当前文本光标y位置的微小差异)来设置SliderPosition

我不知道scrollBar是否来自您问题中的textedit.verticalScrollBar()指针。这有点冗长,但这可以作为解决方法。