110QLayoutPrivate::QLayoutPrivate()
111 : QObjectPrivate(), insideSpacing(-1), userLeftMargin(-1), userTopMargin(-1), userRightMargin(-1),
112 userBottomMargin(-1), topLevel(
false), enabled(
true), activated(
true), autoNewChild(
false),
113 horizontalConstraint(QLayout::SetDefaultConstraint), verticalConstraint(QLayout::SetDefaultConstraint), menubar(
nullptr)
147QSpacerItem *QLayoutPrivate::createSpacerItem(
const QLayout *layout,
int w,
int h, QSizePolicy::Policy hPolicy, QSizePolicy::Policy vPolicy)
149 if (spacerItemFactoryMethod)
150 if (QSpacerItem *si = (*spacerItemFactoryMethod)(layout, w, h, hPolicy, vPolicy))
152 return new QSpacerItem(w, h, hPolicy, vPolicy);
338void QLayout::getContentsMargins(
int *left,
int *top,
int *right,
int *bottom)
const
341 d->getMargin(left, d->userLeftMargin, QStyle::PM_LayoutLeftMargin);
342 d->getMargin(top, d->userTopMargin, QStyle::PM_LayoutTopMargin);
343 d->getMargin(right, d->userRightMargin, QStyle::PM_LayoutRightMargin);
344 d->getMargin(bottom, d->userBottomMargin, QStyle::PM_LayoutBottomMargin);
357QMargins QLayout::contentsMargins()
const
359 int left, top, right, bottom;
360 getContentsMargins(&left, &top, &right, &bottom);
361 return QMargins(left, top, right, bottom);
372QRect QLayout::contentsRect()
const
375 int left, top, right, bottom;
376 getContentsMargins(&left, &top, &right, &bottom);
377 return d->rect.adjusted(+left, +top, -right, -bottom);
489void QLayoutPrivate::doResize()
492 QWidget *mw = q->parentWidget();
493 QRect rect = mw->testAttribute(Qt::WA_LayoutOnEntireRect) ? mw->rect() : mw->contentsRect();
494 const int mbh = menuBarHeightForWidth(menubar, rect.width());
495 const int mbTop = rect.top();
496 rect.setTop(mbTop + mbh);
497 q->setGeometry(rect);
499 menubar->setGeometry(rect.left(), mbTop, rect.width(), mbh);
509void QLayout::widgetEvent(QEvent *e)
512 const QEvent::Type type = e->type();
513 if (!d->enabled && type != QEvent::ChildRemoved)
523 case QEvent::ChildRemoved:
525 QChildEvent *c = (QChildEvent *)e;
526 QObject *child = c->child();
527 QObjectPrivate *op = QObjectPrivate::get(child);
529 if (child == d->menubar)
530 d->menubar =
nullptr;
531 removeWidgetRecursively(
this, child);
535 case QEvent::LayoutRequest:
536 if (
static_cast<QWidget *>(parent())->isVisible())
564int QLayout::totalMinimumHeightForWidth(
int w)
const
569 QWidget *parent = parentWidget();
570 parent->ensurePolished();
571 QWidgetPrivate *wd = parent->d_func();
572 side += wd->leftmargin + wd->rightmargin;
573 top += wd->topmargin + wd->bottommargin;
575 int h = minimumHeightForWidth(w - side) + top +
576 menuBarHeightForWidth(d->menubar, w);
584int QLayout::totalHeightForWidth(
int w)
const
589 QWidget *parent = parentWidget();
590 parent->ensurePolished();
591 QWidgetPrivate *wd = parent->d_func();
592 side += wd->leftmargin + wd->rightmargin;
593 top += wd->topmargin + wd->bottommargin;
595 int h = heightForWidth(w - side) + top +
596 menuBarHeightForWidth(d->menubar, w);
625QSize QLayout::totalSizeHint()
const
630 QWidget *pw = parentWidget();
631 pw->ensurePolished();
632 QWidgetPrivate *wd = pw->d_func();
633 side += wd->leftmargin + wd->rightmargin;
634 top += wd->topmargin + wd->bottommargin;
637 QSize s = sizeHint();
638 if (hasHeightForWidth())
639 s.setHeight(heightForWidth(s.width() + side));
640 top += menuBarHeightForWidth(d->menubar, s.width());
641 return s + QSize(side, top);
648QSize QLayout::totalMaximumSize()
const
653 QWidget *pw = parentWidget();
654 pw->ensurePolished();
655 QWidgetPrivate *wd = pw->d_func();
656 side += wd->leftmargin + wd->rightmargin;
657 top += wd->topmargin + wd->bottommargin;
660 QSize s = maximumSize();
661 top += menuBarHeightForWidth(d->menubar, s.width());
664 s = QSize(qMin(s.width() + side, QLAYOUTSIZE_MAX),
665 qMin(s.height() + top, QLAYOUTSIZE_MAX));
732void QLayoutPrivate::reparentChildWidgets(QWidget *mw)
737 if (menubar && menubar->parentWidget() != mw)
738 menubar->setParent(mw);
740 bool mwVisible = mw && mw->isVisible();
741 for (
int i = 0; i < n; ++i) {
742 QLayoutItem *item = q->itemAt(i);
743 if (QWidget *w = item->widget()) {
744 QWidget *pw = w->parentWidget();
746 if (Q_UNLIKELY(pw && pw != mw && layoutDebug())) {
747 qWarning(
"QLayout::addChildLayout: widget %s \"%ls\" in wrong parent; moved to correct parent",
748 w->metaObject()->className(), qUtf16Printable(w->objectName()));
751 bool needShow = mwVisible && !QWidgetPrivate::get(w)->isExplicitlyHidden();
755 QMetaObject::invokeMethod(w,
"_q_showIfNotHidden", Qt::QueuedConnection);
756 }
else if (QLayout *l = item->layout()) {
757 l->d_func()->reparentChildWidgets(mw);
766bool QLayoutPrivate::checkWidget(QWidget *widget)
const
769 if (Q_UNLIKELY(!widget)) {
770 qWarning(
"QLayout: Cannot add a null widget to %s/%ls", q->metaObject()->className(),
771 qUtf16Printable(q->objectName()));
774 if (Q_UNLIKELY(widget == q->parentWidget())) {
775 qWarning(
"QLayout: Cannot add parent widget %s/%ls to its child layout %s/%ls",
776 widget->metaObject()->className(), qUtf16Printable(widget->objectName()),
777 q->metaObject()->className(), qUtf16Printable(q->objectName()));
812void QLayout::addChildWidget(QWidget *w)
814 QWidget *mw = parentWidget();
815 QWidget *pw = w->parentWidget();
819 if (pw && w->testAttribute(Qt::WA_LaidOut)) {
820 QLayout *l = pw->layout();
821 if (l && removeWidgetRecursively(l, w)) {
823 if (Q_UNLIKELY(layoutDebug()))
824 qWarning(
"QLayout::addChildWidget: %s \"%ls\" is already in a layout; moved to new layout",
825 w->metaObject()->className(), qUtf16Printable(w->objectName()));
829 if (pw && mw && pw != mw) {
831 if (Q_UNLIKELY(layoutDebug()))
832 qWarning(
"QLayout::addChildWidget: %s \"%ls\" in wrong parent; moved to correct parent",
833 w->metaObject()->className(), qUtf16Printable(w->objectName()));
837 bool needShow = mw && mw->isVisible() && !QWidgetPrivate::get(w)->isExplicitlyHidden();
840 w->setAttribute(Qt::WA_LaidOut);
842 QMetaObject::invokeMethod(w,
"_q_showIfNotHidden", Qt::QueuedConnection);
939void QLayout::update()
941 QLayout *layout =
this;
942 while (layout && layout->d_func()->activated) {
943 layout->d_func()->activated =
false;
944 if (layout->d_func()->topLevel) {
945 Q_ASSERT(layout->parent()->isWidgetType());
946 QWidget *mw =
static_cast<QWidget*>(layout->parent());
947 QCoreApplication::postEvent(mw,
new QEvent(QEvent::LayoutRequest));
950 layout =
static_cast<QLayout*>(layout->parent());
963bool QLayout::activate()
966 if (!d->enabled || !parent())
969 return static_cast<QLayout*>(parent())->activate();
972 QWidget *mw =
static_cast<QWidget*>(parent());
973 if (Q_UNLIKELY(!mw)) {
974 qWarning(
"QLayout::activate: %s \"%ls\" does not have a main widget",
975 metaObject()->className(), qUtf16Printable(objectName()));
978 activateRecursiveHelper(
this);
980 QWidgetPrivate *md = mw->d_func();
981 uint explMin = md->extra ? md->extra->explicitMinSize : 0;
982 uint explMax = md->extra ? md->extra->explicitMaxSize : 0;
989 QSize minSize(-1, -1);
990 QSize maxSize(-2, -2);
993 constexpr QSize empty(0, 0);
994 QSize totalSzH = empty;
995 QSize totalMinSz = empty;
996 QSize totalMaxSz = empty;
998 switch (d->verticalConstraint) {
1000 totalSzH = totalSizeHint();
1001 minSize.setHeight(totalSzH.height());
1002 maxSize.setHeight(totalSzH.height());
1004 case SetMinimumSize:
1005 totalMinSz = totalMinimumSize();
1006 minSize.setHeight(totalMinSz.height());
1008 case SetMaximumSize:
1009 totalMaxSz = totalMaximumSize();
1010 maxSize.setHeight(totalMaxSz.height());
1012 case SetMinAndMaxSize:
1013 totalMinSz = totalMinimumSize();
1014 totalMaxSz = totalMaximumSize();
1015 minSize.setHeight(totalMinSz.height());
1016 maxSize.setHeight(totalMaxSz.height());
1018 case SetDefaultConstraint: {
1019 bool heightSet = explMin & Qt::Vertical;
1020 if (mw->isWindow()) {
1022 totalMinSz = totalMinimumSize();
1023 minSize.setHeight(totalMinSz.height());
1025 minSize.setHeight(mw->minimumHeight());
1028 minSize.setHeight(heightSet ? mw->minimumHeight() : 0);
1032 case SetNoConstraint:
1035 switch (d->horizontalConstraint) {
1037 if (totalSzH == empty)
1038 totalSzH = totalSizeHint();
1039 minSize.setWidth(totalSzH.width());
1040 maxSize.setWidth(totalSzH.width());
1042 case SetMinimumSize:
1043 if (totalMinSz == empty)
1044 totalMinSz = totalMinimumSize();
1045 minSize.setWidth(totalMinSz.width());
1047 case SetMaximumSize:
1048 if (totalMaxSz == empty)
1049 totalMaxSz = totalMaximumSize();
1050 maxSize.setWidth(totalMaxSz.width());
1052 case SetMinAndMaxSize:
1053 if (totalMinSz == empty)
1054 totalMinSz = totalMinimumSize();
1055 if (totalMaxSz == empty)
1056 totalMaxSz = totalMaximumSize();
1058 minSize.setWidth(totalMinSz.width());
1059 maxSize.setWidth(totalMaxSz.width());
1061 case SetDefaultConstraint: {
1062 const bool widthSet = explMin & Qt::Horizontal;
1063 if (mw->isWindow()) {
1065 if (totalMinSz == empty)
1066 totalMinSz = totalMinimumSize();
1067 minSize.setWidth(totalMinSz.width());
1069 minSize.setWidth(mw->minimumWidth());
1072 minSize.setWidth(widthSet ? mw->minimumWidth() : 0);
1076 case SetNoConstraint:
1079 if (minSize == maxSize) {
1080 mw->setFixedSize(minSize);
1091 if (minSize.isValid())
1092 mw->setMinimumSize(minSize);
1093 else if (minSize.width() >= 0)
1094 mw->setMinimumWidth(minSize.width());
1095 else if (minSize.height() >= 0)
1096 mw->setMinimumHeight(minSize.height());
1099 if (maxSize.isValid())
1100 mw->setMaximumSize(maxSize);
1101 else if (maxSize.width() >= 0)
1102 mw->setMaximumWidth(maxSize.width());
1103 else if (maxSize.height() >= 0)
1104 mw->setMaximumHeight(maxSize.height());
1110 md->extra->explicitMinSize = explMin;
1111 md->extra->explicitMaxSize = explMax;
1114 mw->updateGeometry();
1142QLayoutItem *QLayout::replaceWidget(QWidget *from, QWidget *to, Qt::FindChildOptions options)
1151 QLayoutItem *item =
nullptr;
1152 for (
int u = 0; u < count(); ++u) {
1157 if (item->widget() == from) {
1162 if (item->layout() && (options & Qt::FindChildrenRecursively)) {
1163 QLayoutItem *r = item->layout()->replaceWidget(from, to, options);
1172 QLayoutItem *newitem =
new QWidgetItem(to);
1173 newitem->setAlignment(item->alignment());
1174 QLayoutItem *r = d->replaceAt(index, newitem);