Остановить QTextCursor::insertText() от изменения диапазона полосы прокрутки QTextDocument
У меня есть QTextEdit
который содержит QTextDocument
, который программно редактируется с использованием QTextCursor
интерфейс. Документ редактируется с QTextCursor::insertText()
,
Я загружаю редактируемый текстовый файл кусками, поэтому начальный размер QTextDocument
может быть только 20 строк, даже если документ 100000 строк. Тем не менее, я хочу QTextEdit
полоса прокрутки, чтобы отобразить полный размер документа, а не только 20-строчный документ, который он отображает в данный момент.
Диапазон полосы прокрутки QTextEdit устанавливается с QScrollBar::setMaximum()
которая корректирует полосу прокрутки до нужного размера при первом открытии файла, но когда QTextCursor::insertText()
называется QScrollBar
Диапазон пересчитывается.
Я уже пробовал звонить QScrollBar::setMaximum()
после каждого QTextCursor::insertText()
событие, но это просто делает весь интерфейс вяленым и неаккуратным.
Есть ли способ сохранить диапазон QScrollBar
в то время как QTextDocument
модифицируется?
2 ответа
Я использую QT для Python, но я думаю, что подполье то же самое.
- Вы решаете, что размер страницы допустим.(A4 = ширина =797, высота =1023)
- Вы вставляете текст.
- если вы вставляете текст, текстовым курсором является нижняя строка документа.
- Вы получаете прямоугольник.
- Вы делите прямоугольник по размеру страницы.
- Если длина текста 20 строк равна 1 странице, строка 20 является последней из одной страницы. Вероятно, эта нижняя высота страницы равна 1023, если вы установите высоту 1023. current_bottomline + cursor.height > 1023*pageheight = current_page last_bottomline + cursor.height>1023*lastpageheiht = max_page
- Вы изменяете размер текста.(797,1023* страница)
Если вы удаляете тексты клавишей возврата или клавишей удаления, вы должны пересчитать последнюю строку дна (я рекомендую выполнить эту проверку в KeyEvent).
QTextCursor.movePosition(QtGui.QTextCursor.End,QtGui.QTextCursor.MoveAnchor,1)
И вы получаете курсор Rect()
- Вы делите высоту на единицу измерения размера А4.
- если высота 102300, страница будет 100.
- установить размер страницы до 100.
- Вы изменяете размер textedit изменяет размер (797,1023 * страница)
- ты можешь получить
textedit.verticalScrollBar()
- Вы устанавливаете verticalScrollBar() setMaximum(высота последней страницы)
- Вы устанавливаете SliderPosition с помощью setSliderPosition(то же значение или небольшая разница текущей позиции курсора y)
Я не мог знать, был ли scrollBar взят из указателя textedit.verticalScrollBar() из вашего вопроса. Это немного многословно, но это может быть способом решения.
Да. Вы бы зависели от деталей реализации. В 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
от вмешательства с вами.