Изменение размера QTextEdit в соответствии с высотой текста: maximumViewportSize()
Я пытаюсь использовать виджет QTextEdit внутри формы, содержащей несколько виджетов QT. Сама форма находится внутри QScrollArea, который является центральным виджетом для окна. Мое намерение состоит в том, что любая необходимая прокрутка будет происходить в основной QScrollArea (а не внутри каких-либо виджетов), и любые виджеты внутри автоматически изменят свою высоту, чтобы держать их содержимое.
Я попытался реализовать автоматическое изменение размера высоты с помощью QTextEdit, но столкнулся с странный вопрос. Я создал подкласс QTextEdit и reimplemented sizeHint () следующим образом:
QSize OperationEditor::sizeHint() const {
QSize sizehint = QTextBrowser::sizeHint();
sizehint.setHeight(this->fitted_height);
return sizehint;
}
this - >fitted_height поддерживается в актуальном состоянии через этот слот, который подключен к сигналу "contentsChanged()" QTextEdit:
void OperationEditor::fitHeightToDocument() {
this->document()->setTextWidth(this->viewport()->width());
QSize document_size(this->document()->size().toSize());
this->fitted_height = document_size.height();
this->updateGeometry();
}
политика размера подкласса QTextEdit:
this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
Я принял этот подход после прочтения этот пост.
вот моя проблема:
по мере того как QTextEdit постепенно изменяет размер для заполнения окно, оно перестает увеличиваться и начинает прокручиваться в QTextEdit, независимо от того, какая высота возвращается из sizeHint(). Если у меня изначально есть sizehint (), возвращающий некоторое большое постоянное число, то QTextEdit очень большой и содержится хорошо во внешней QScrollArea, как и следовало ожидать. Однако, если sizeHint постепенно регулирует размер QTextEdit, а не просто делает его действительно большим для запуска, то он завершается, когда заполняет текущее окно и начинает прокрутку вместо возрастающий.
Я проследил эту проблему, чтобы быть, независимо от того, что мой sizeHint() возвращает, он никогда не будет изменять размер QTextEdit больше, чем значение, возвращаемое из maximumViewportSize (), который наследуется от QAbstractScrollArea. Обратите внимание, что это не то же самое число, что viewport()->maximumSize(). Я не могу понять, как установить это значение.
глядя на исходный код QT, maximumViewportSize () возвращает " размер окна просмотра, как если бы полосы прокрутки не имели допустимый диапазон прокрутки."Это значение в основном вычисляется как текущий размер виджета минус (2 * ширина рамки + поля) плюс любые ширины/высоты полосы прокрутки. Это не имеет большого смысла для меня, и мне непонятно, почему это число будет использоваться где-либо таким образом, чтобы заменить реализацию sizehint() подкласса. Кроме того, кажется странным, что одно целое число "frameWidth" используется при вычислении как ширины, так и высоты.
может кто-нибудь, пожалуйста, пролить свет на этом? Я подозреваю,что здесь виновато мое плохое понимание движка компоновки QT.
Edit: после первоначальной публикации у меня возникла идея переопределить maximumViewportSize (), чтобы вернуть то же самое, что и sizeHint(). К сожалению, это не сработало, поскольку у меня все еще есть та же проблема.
2 ответов
Я решил эту проблему. Было 2 вещи, которые я должен был сделать, чтобы заставить его работать:
поднимитесь по иерархии виджетов и убедитесь, что все политики размера имеют смысл, чтобы гарантировать, что если какой-либо дочерний виджет хочет быть большим/маленьким, то Родительский виджет захочет быть тем же самым.
Это основной источник исправления. Оказывается, поскольку QTextEdit находится внутри QFrame, который является основным виджетом в QScrollArea, Qscrollarea имеет ограничение, которое не будет изменять размер внутреннего виджета, если свойство widgetResizable не имеет значения true. Документация для этого здесь:http://doc.qt.io/qt-4.8/qscrollarea.html#widgetResizable-prop. Документация не была мне понятна, пока я не поиграл с этой настройкой и не заставил ее работать. Из документов кажется, что это свойство имеет дело только с временами, когда основная область прокрутки хочет изменить размер виджета (т. е. от родителя к потомку). Это на самом деле означает, что если основной виджет в области прокрутки хочет изменить размер (т. е. дочерний для родительского), то этот параметр должен быть установлен в true.
Итак, мораль истории заключается в том, что код QTextEdit был правильным в переопределении sizeHint, но QScrollArea игнорировал значение, возвращаемое из sizeHint основного фрейма.
Ура! Работает!
Вы можете попробовать параметр minimumSize
свойства QTextEdit
чтобы увидеть, заставит ли это макет расти.
Я не понимаю большую часть схемы компоновки Qt, но установка минимального и максимального размера в значительной степени делает то, что я хочу. Ну, по крайней мере, большую часть времени.