загадочное adjustSize

adjustSize расчет размеров виджета и всех его вложенных виджетов.

Обратите внимание , что в ui формах adjustSize может вызвать только для главного топового виджета (напрмер QDialog). А точнее еще можно делать для QTabWindget например и возможно еще для некоторых объектов.

Если для этих виджетов не выбрать тип компоновщика (Layout Horizontally,
Layout Vertically,
QFormLayout,
QGridLayout) они будут помечены красным знаком (остановка запрещена).

фотка 1

В двух словах adjustSize обходит все дочерние виджеты и вычисляет суммарный их sizeHint() и в конце (это важно) делает resize c указанием этого размера.

sizeHint() виджетов (и компоновщиков) мы можем переопределять!

То есть после adjustSize будет вызвано событие QResizeEvent.

В обработчиках событий (типа QResizeEvent) не надо вызывать adjustSize , иначе может произойти зацикливание.

void QWidget::adjustSize()
{
    Q_D(QWidget);
    ensurePolished();
    QSize s = d->adjustedSize();

    if (d->layout)
        d->layout->activate();

    if (s.isValid())
        resize(s);
}

Комментарии из кода разработчиков Qt:

Adjusts the size of the widget to fit its contents.

This function uses sizeHint() if it is valid, i.e., the size hint's width and height are != 0. Otherwise, it sets the size to the children rectangle that covers all child widgets (the union of all child widge rectangles).

For windows, the screen size is also taken into account. If the sizeHint() is less than (200, 100) and the size policy is {QSizePolicy::Expanding} {expanding}, the window will be at least (200, 100). The maximum size of a window is 2/3 of the screen's width and height.
see sizeHint(), childrenRect().

void QWidget::ensurePolished() const
{
    Q_D(const QWidget);

    const QMetaObject *m = metaObject();
    if (m == d->polished)
        return;
    d->polished = m;

    QEvent e(QEvent::Polish);
    QCoreApplication::sendEvent(const_cast(this), &e);

    // polish children after 'this'
    QList children = d->children;
    for (int i = 0; i < children.size(); ++i) {
        QObject *o = children.at(i);
        if(!o->isWidgetType())
            continue;
        if (QWidget *w = qobject_cast(o))
            w->ensurePolished();
    }

    if (d->parent && d->sendChildEvents) {
        QChildEvent e(QEvent::ChildPolished, const_cast(this));
        QCoreApplication::sendEvent(d->parent, &e);
    }
}

Ensures that the widget has been polished by QStyle (i.e., has a proper font and palette).

QWidget calls this function after it has been fully constructed but before it is shown the very first time. You can call this function if you want to ensure that the widget is polished before doing an operation, e.g., the correct font size might be needed in the widget's sizeHint() reimplementation. Note that this function is called from the default implementation of sizeHint().

Polishing is useful for final initialization that must happen after all constructors (from base classes as well as from subclasses) have been called.

If you need to change some settings when a widget is polished, reimplement event() and handle the QEvent::Polish event type.

Note: The function is declared const so that it can be called from other const functions (e.g., sizeHint()).

QSize QWidgetPrivate::adjustedSize() const
{
    Q_Q(const QWidget);

    QSize s = q->sizeHint();

    if (q->isWindow()) {
        Qt::Orientations exp;
        if (layout) {
            if (layout->hasHeightForWidth())
                s.setHeight(layout->totalHeightForWidth(s.width()));
            exp = layout->expandingDirections();
        } else
        {
            if (q->sizePolicy().hasHeightForWidth())
                s.setHeight(q->heightForWidth(s.width()));
            exp = q->sizePolicy().expandingDirections();
        }
        if (exp & Qt::Horizontal)
            s.setWidth(qMax(s.width(), 200));
        if (exp & Qt::Vertical)
            s.setHeight(qMax(s.height(), 100));
#if defined(Q_WS_X11)
        QRect screen = QApplication::desktop()->screenGeometry(q->x11Info().screen());
#else // all others
        QRect screen = QApplication::desktop()->screenGeometry(q->pos());
#endif
#if defined (Q_WS_WINCE) || defined (Q_OS_SYMBIAN)
        s.setWidth(qMin(s.width(), screen.width()));
        s.setHeight(qMin(s.height(), screen.height()));
#else
        s.setWidth(qMin(s.width(), screen.width()*2/3));
        s.setHeight(qMin(s.height(), screen.height()*2/3));
#endif
        if (QTLWExtra *extra = maybeTopData())
            extra->sizeAdjusted = true;
    }

    if (!s.isValid()) {
        QRect r = q->childrenRect(); // get children rectangle
        if (r.isNull())
            return s;
        s = r.size() + QSize(2 * r.x(), 2 * r.y());
    }

    return s;
}

resize вызывается последним для изменения размера виджета:


void QWidget::resize(const QSize &s)
{
    Q_D(QWidget);
    setAttribute(Qt::WA_Resized);
    if (testAttribute(Qt::WA_WState_Created)) {
        d->setGeometry_sys(geometry().x(), geometry().y(), s.width(), s.height(), false);
        d->setDirtyOpaqueRegion();
    } else {
        data->crect.setSize(s.boundedTo(maximumSize()).expandedTo(minimumSize()));
        setAttribute(Qt::WA_PendingResizeEvent);
    }
}