Остановить QTextCursor :: insertText () от изменения диапазона полосы прокрутки QTextDocument

у меня есть QTextEdit который содержит QTextDocument, который программно редактируется с использованием QTextCursor интерфейс. Документ редактируется с QTextCursor::insertText(),

Я загружаю редактируемый текстовый файл кусками, поэтому начальный размер QTextDocument может быть только 20 строк, даже если документ 100 000 строк. Тем не менее, я хочу QTextEdit полоса прокрутки, чтобы отобразить полный размер документа, а не только 20-строчный документ, который он отображает в данный момент.

Диапазон полосы прокрутки QTextEdit устанавливается с QScrollBar::setMaximum() которая корректирует полосу прокрутки до нужного размера при первом открытии файла, но когда QTextCursor::insertText() называется QScrollBarДиапазон пересчитывается.

Я уже пробовал звонить QScrollBar::setMaximum() после каждого QTextCursor::insertText() событие, но это просто делает весь интерфейс вяленым и неаккуратным.

Есть ли способ сохранить диапазон QScrollBar в то время как QTextDocument модифицируется?

1

Решение

Да. Вы бы зависели от деталей реализации. В QTextEditPrivate :: Init (), установлено следующее соединение:

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

Вот, q имеет тип QTextEdit* и является Q-указатель к объекту API. Таким образом, вам нужно отключить это соединение и самостоятельно управлять полосами прокрутки:

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 от вмешательства с вами.

0

Другие решения

Я использую QT для Python, но я думаю, что подполье то же самое.

  1. Вы решаете, что размер страницы допустим. (A4 = ширина = 797, высота = 1023)
  2. Вы вставляете текст.
  3. если вы вставляете текст, текстовым курсором является нижняя строка документа.
  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. Если вы удаляете тексты клавишей возврата или клавишей удаления, вы должны пересчитать последнюю строку дна (я рекомендую выполнить эту проверку в KeyEvent).QTextCursor.movePosition(QtGui.QTextCursor.End,QtGui.QTextCursor.MoveAnchor,1)

  9. И вы получаете курсорRect ()

  10. Вы делите высоту на единицу измерения размера А4.
  11. если высота 102300, страница будет 100.
  12. установить размер страницы до 100.
  13. Вы изменяете размер textedit изменяет размер (797,1023 * страница)
  14. ты можешь получить textedit.verticalScrollBar()
  15. Вы устанавливаете verticalScrollBar () setMaximum (высота последней страницы)
  16. Вы устанавливаете SliderPosition с помощью setSliderPosition (то же значение или небольшая разница текущей позиции курсора y)

Я не мог знать, был ли scrollBar взят из указателя textedit.verticalScrollBar () из вашего вопроса. Это немного многословно, но это может быть способом решения.

0

По вопросам рекламы [email protected]