Что вводит в заблуждение первоначально

Покопавшись в исходниках Qt 4.8.1 проясняются кое-какие на наш взгляд важные для понимания логики моменты.


Не нужно проставлять размеры виджетам явно

Может показаться, что явное указание размера виджета правильный подход, но похоже это не так. Резиновость виджета это главный плюс Qt.

А для этого никаких FixedSize не надо , и даже setMinimumSize не требуется. Точнее требуется в очень специфичных задачах.

Все будет прекрасно работать без фиксаций размеров.

resizeEvent() paintEvent(),moveEvent()..

Первое небольшое открытие , а точнее что удивило дилетанта - это например в QWidget так называемые обработчики событий типа resizeEvent() или paintEvent() - ОНИ ПУСТЫЕ!

Как это понимать?

То есть они определены, но там ничего нет (пусто)! Все в таком духе:

void QWidget::resizeEvent(QResizeEvent * /* event */)
{
}

И тут в исходниках Qt перед определением функции resizeEvent есть очень правильные (от разработчиков) комментарии к этой функции, зачем она нужна :

/*!
    This event handler can be reimplemented in a subclass to receive
    widget resize events which are passed in the a event parameter.
    When resizeEvent() is called, the widget already has its new
    geometry. The old size is accessible through
    QResizeEvent::oldSize().

    The widget will be erased and receive a paint event immediately
    after processing the resize event. No drawing need be (or should
    be) done inside this handler.


    sa moveEvent(), event(), resize(), QResizeEvent, paintEvent(),
        {Scribble Example}
*/

Примечательно , тут говорится , что виджет после отработки resizeEvent будет стерт и отрисован заново. И здесь в resizeEvent НЕ надо ничего рисовать.

Вывод: resizeEvent это по сути callback , в котором нам передают информацию , что кто-то уже установил новый размер нашему виджету, нам НЕ предлагается изменять эти размеры или что-то рисовать на этом виджете , просто нам сигнализируют об изменении размера.

Где-то на начальном этапе появляются вопросы :
Кем будет стерт наш виджет?
Кем будет отрисован заново?
Кто в наш виджет посылает resizeEvent?

Родитель - потомок

На самом деле практически всегда у виджета есть родитель (parent), он так же может быть виджетом , а может быть и только обджэктом(QObject). И очень редко родителя может не быть.

Очень важно знать и понимать всю иерархию виджетов до самого верхнего окна приложения от вашего текущего.

Но как быть , если иерархия частично скрыта в исходниках?
Правильно изучать исходники или воспользоваться полезной функцией, которая раскручивает все объекты вплоть до вершины.

Почему это важно? Дело в том, что потомок может например поменять размеры своему контенту, но свои размеры (свой контур окна) ему может поменять только родитель.

То есть потомок виджет живет в пределах окна родителя. И это в принципе правильно...

Динамическое изменение размера виджету

На счет изменения размера виджета потомка. Чтобы изменить размер виджету потомку (из кода самого потомка) по его текущему контенту можно просто родителю вызвать resize , то есть (parentWidget()->resize(sz0)). И это сработает нормально.

Еще очень важно проверять политики размеров, которые вы установили на формах ui. Часто бывает попробовал установить sizePolicy одному из виджетов и забыл. Потом мучаешься , не можешь понять почему не так работает.

На самом деле sizePolicy сначала лучше устанавливать всем виджетам Preffred (horizontal / vertical Stretch по нулям ).

minimumSize устанавливаем тоже всем виджетам по нулям .

maximumSize устанавливаем тоже всем виджетам по максимуму (16777215) .

А потом когда все заработает как надо приходит понимание , что ничего менять и не надо.