1

I have a QTextEdit that contains a QTextDocument, which is being programatically edited using the QTextCursor interface. The document is being edited with QTextCursor::insertText().

I load the text file being edited in chunks, so the initial size of the QTextDocument might only be 20 lines even though the document is 100,000 lines. However, I want the QTextEdit scrollbar to reflect the full size of the document instead of just the 20 line document it's currently displaying.

The QTextEdit's scrollbar range is set with QScrollBar::setMaximum() which adjusts the scrollbar to the proper size on the initial opening of the file, but when QTextCursor::insertText() is called the QScrollBar's range is recalculated.

I've already tried calling QScrollBar::setMaximum() after each QTextCursor::insertText() event, but it just makes the whole UI jerky and sloppy.

Is there any way to keep the range of the QScrollBar while the QTextDocument is being modified?

John V.
  • 21
  • 1

1 Answers1

0

Yes. You'd depend on the implementation detail. In QTextEditPrivate::init(), the following connection is made:

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

Here, q is of the type QTextEdit* and is the Q-pointer to the API object. Thus, you'd need to disconnect this connection, and manage the scroll bars on your own:

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()));
}

Hopefully, this should be enough to prevent QTextEdit from interfering with you.

Kuba hasn't forgotten Monica
  • 88,505
  • 13
  • 129
  • 275