Подтвердить что ты не робот

Изменение размера QT QTextEdit для соответствия высоте текста: maximumViewportSize()

Я пытаюсь использовать виджет QTextEdit внутри формы, содержащей несколько виджетов QT. Сама форма находится внутри QScrollArea, которая является центральным виджетами для окна. Мое намерение заключается в том, что любая необходимая прокрутка будет проходить в основной QScrollArea (а не внутри любых виджетов), и любые виджеты внутри автоматически изменят их высоту, чтобы сохранить их содержимое.

Я попытался реализовать автоматическое изменение высоты с помощью QTextEdit, но столкнулся с нечетной проблемой. Я создал подкласс QTextEdit и переопределил sizeHint() следующим образом:

QSize OperationEditor::sizeHint() const {
  QSize sizehint = QTextBrowser::sizeHint();
  sizehint.setHeight(this->fitted_height);
  return sizehint;
}

this- > installed_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, а не просто делает его действительно большим, чтобы начать, тогда он заканчивается, когда он заполняет текущее окно и начинает прокрутку, а не растет.

Я проследил эту проблему в том, что независимо от того, что возвращает мой размерHint(), он никогда не будет изменять размер QTextEdit больше, чем значение, возвращаемое из maximumViewportSize(), которое унаследовано от QAbstractScrollArea. Обратите внимание, что это не тот же номер, что и viewport() → maximumSize(). Я не могу понять, как установить это значение.

При взгляде на исходный код QT, максимальныйViewportSize() возвращает "размер окна просмотра, как если бы полосы прокрутки не имели допустимого диапазона прокрутки". Это значение в основном вычисляется как текущий размер виджета минус (2 * frameWidth + margin) плюс любые ширины/высоты полосы прокрутки. Это не имеет для меня большого смысла, и мне непонятно, почему этот номер будет использоваться где угодно, чтобы переуступить реализацию sub-class sizeHint(). Кроме того, кажется странным, что одно целое число "frameWidth" используется для вычисления ширины и высоты.

Может кто-нибудь пролить свет на это? Я подозреваю, что мое плохое понимание механизма компоновки QT здесь виновато.

Изменить: после первоначальной публикации этого вопроса у меня возникла идея переопределить maximumViewportSize(), чтобы вернуть то же самое, что и sizeHint(). К сожалению, это не сработало, поскольку у меня все еще есть одна и та же проблема.

4b9b3361

Ответ 1

Я решил эту проблему. Было 2 вещи, которые я должен был сделать, чтобы заставить его работать:

  • Поднимите иерархию виджетов и убедитесь, что все политики размера имеют смысл гарантировать, что если какой-либо дочерний виджет хотел быть большим/маленьким, тогда родительский виджет хотел бы быть тем же самым.

  • Это основной источник исправления. Оказывается, поскольку QTextEdit находится внутри QFrame, который является основным виджемом в QScrollArea, QScrollArea имеет ограничение, что он не будет изменять размер внутреннего виджета, если свойство "widgetResizable" не является истинным. Документация для этого находится здесь: http://doc.qt.io/qt-4.8/qscrollarea.html#widgetResizable-prop. Документация мне не была понятна, пока я не играл с этой настройкой и не получил ее на работу. Из документов, похоже, что это свойство имеет дело только со временем, когда основная область прокрутки хочет изменить размер виджета (то есть от родителя к дочернему). Фактически это означает, что если главный виджет в области прокрутки хочет когда-либо изменить размер (то есть дочерний элемент для родителя), тогда этот параметр должен быть установлен в true.

Итак, мораль этой истории заключается в том, что код QTextEdit был прав в переопределении sizeHint, но QScrollArea игнорировал значение, возвращаемое из основного размера кадра.

Ура! Это работает!

Ответ 2

Вы можете попробовать установить minimumSize свойство QTextEdit, чтобы убедиться, что это заставляет макет расти.

Я не понимаю большую часть схемы компоновки Qt, но установка минимального и максимального размера в значительной степени делает то, что я хочу, чтобы он делал. Ну, в большинстве случаев в любом случае.