Изменение размера QTextEdit QT в соответствии с высотой текста: maximumViewportSize () - PullRequest
11 голосов
/ 16 июня 2010

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

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

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

this-> fit_height поддерживается в актуальном состоянии через этот слот, который подключен к сигналу QTextEdit "contentsChanged ()":

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 * frameWidth + margins) плюс любая ширина / высота полосы прокрутки. Это не имеет большого смысла для меня, и мне не ясно, почему это число будет использоваться где-либо таким образом, который заменяет реализацию sizeHint () подкласса. Кроме того, кажется странным, что одно целое число «frameWidth» используется для вычисления как ширины, так и высоты.

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

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

Ответы [ 2 ]

10 голосов
/ 19 июня 2010

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

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

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

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

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

0 голосов
/ 16 июня 2010

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

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

...