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);
368QMargins QLayout::contentsMargins()
const
370 int left, top, right, bottom;
371 getContentsMargins(&left, &top, &right, &bottom);
372 return QMargins(left, top, right, bottom);
383QRect QLayout::contentsRect()
const
386 int left, top, right, bottom;
387 getContentsMargins(&left, &top, &right, &bottom);
388 return d->rect.adjusted(+left, +top, -right, -bottom);
500void QLayoutPrivate::doResize()
503 QWidget *mw = q->parentWidget();
504 QRect rect = mw->testAttribute(Qt::WA_LayoutOnEntireRect) ? mw->rect() : mw->contentsRect();
505 const int mbh = menuBarHeightForWidth(menubar, rect.width());
506 const int mbTop = rect.top();
507 rect.setTop(mbTop + mbh);
508 q->setGeometry(rect);
510 menubar->setGeometry(rect.left(), mbTop, rect.width(), mbh);
520void QLayout::widgetEvent(QEvent *e)
523 const QEvent::Type type = e->type();
524 if (!d->enabled && type != QEvent::ChildRemoved)
534 case QEvent::ChildRemoved:
536 QChildEvent *c = (QChildEvent *)e;
537 QObject *child = c->child();
538 QObjectPrivate *op = QObjectPrivate::get(child);
540 if (child == d->menubar)
541 d->menubar =
nullptr;
542 removeWidgetRecursively(
this, child);
546 case QEvent::LayoutRequest:
547 if (
static_cast<QWidget *>(parent())->isVisible())
575int QLayout::totalMinimumHeightForWidth(
int w)
const
580 QWidget *parent = parentWidget();
581 parent->ensurePolished();
582 QWidgetPrivate *wd = parent->d_func();
583 side += wd->leftmargin + wd->rightmargin;
584 top += wd->topmargin + wd->bottommargin;
586 int h = minimumHeightForWidth(w - side) + top +
587 menuBarHeightForWidth(d->menubar, w);
595int QLayout::totalHeightForWidth(
int w)
const
600 QWidget *parent = parentWidget();
601 parent->ensurePolished();
602 QWidgetPrivate *wd = parent->d_func();
603 side += wd->leftmargin + wd->rightmargin;
604 top += wd->topmargin + wd->bottommargin;
606 int h = heightForWidth(w - side) + top +
607 menuBarHeightForWidth(d->menubar, w);
636QSize QLayout::totalSizeHint()
const
641 QWidget *pw = parentWidget();
642 pw->ensurePolished();
643 QWidgetPrivate *wd = pw->d_func();
644 side += wd->leftmargin + wd->rightmargin;
645 top += wd->topmargin + wd->bottommargin;
648 QSize s = sizeHint();
649 if (hasHeightForWidth())
650 s.setHeight(heightForWidth(s.width() + side));
651 top += menuBarHeightForWidth(d->menubar, s.width());
652 return s + QSize(side, top);
659QSize QLayout::totalMaximumSize()
const
664 QWidget *pw = parentWidget();
665 pw->ensurePolished();
666 QWidgetPrivate *wd = pw->d_func();
667 side += wd->leftmargin + wd->rightmargin;
668 top += wd->topmargin + wd->bottommargin;
671 QSize s = maximumSize();
672 top += menuBarHeightForWidth(d->menubar, s.width());
675 s = QSize(qMin(s.width() + side, QLAYOUTSIZE_MAX),
676 qMin(s.height() + top, QLAYOUTSIZE_MAX));
743void QLayoutPrivate::reparentChildWidgets(QWidget *mw)
748 if (menubar && menubar->parentWidget() != mw)
749 menubar->setParent(mw);
751 bool mwVisible = mw && mw->isVisible();
752 for (
int i = 0; i < n; ++i) {
753 QLayoutItem *item = q->itemAt(i);
754 if (QWidget *w = item->widget()) {
755 QWidget *pw = w->parentWidget();
757 if (Q_UNLIKELY(pw && pw != mw && layoutDebug())) {
758 qWarning(
"QLayout::addChildLayout: widget %s \"%ls\" in wrong parent; moved to correct parent",
759 w->metaObject()->className(), qUtf16Printable(w->objectName()));
762 bool needShow = mwVisible && !QWidgetPrivate::get(w)->isExplicitlyHidden();
766 QMetaObject::invokeMethod(w,
"_q_showIfNotHidden", Qt::QueuedConnection);
767 }
else if (QLayout *l = item->layout()) {
768 l->d_func()->reparentChildWidgets(mw);
783bool QLayoutPrivate::checkWidget(QWidget *widget)
const
786 if (Q_UNLIKELY(!widget)) {
787 qWarning(
"QLayout: Cannot add a null widget to %s/%ls", q->metaObject()->className(),
788 qUtf16Printable(q->objectName()));
791 if (Q_UNLIKELY(widget == q->parentWidget())) {
792 qWarning(
"QLayout: Cannot add parent widget %s/%ls to its child layout %s/%ls",
793 widget->metaObject()->className(), qUtf16Printable(widget->objectName()),
794 q->metaObject()->className(), qUtf16Printable(q->objectName()));
829void QLayout::addChildWidget(QWidget *w)
831 QWidget *mw = parentWidget();
832 QWidget *pw = w->parentWidget();
836 if (pw && w->testAttribute(Qt::WA_LaidOut)) {
837 QLayout *l = pw->layout();
838 if (l && removeWidgetRecursively(l, w)) {
840 if (Q_UNLIKELY(layoutDebug()))
841 qWarning(
"QLayout::addChildWidget: %s \"%ls\" is already in a layout; moved to new layout",
842 w->metaObject()->className(), qUtf16Printable(w->objectName()));
846 if (pw && mw && pw != mw) {
848 if (Q_UNLIKELY(layoutDebug()))
849 qWarning(
"QLayout::addChildWidget: %s \"%ls\" in wrong parent; moved to correct parent",
850 w->metaObject()->className(), qUtf16Printable(w->objectName()));
854 bool needShow = mw && mw->isVisible() && !QWidgetPrivate::get(w)->isExplicitlyHidden();
857 w->setAttribute(Qt::WA_LaidOut);
859 QMetaObject::invokeMethod(w,
"_q_showIfNotHidden", Qt::QueuedConnection);
956void QLayout::update()
958 QLayout *layout =
this;
959 while (layout && layout->d_func()->activated) {
960 layout->d_func()->activated =
false;
961 if (layout->d_func()->topLevel) {
962 Q_ASSERT(layout->parent()->isWidgetType());
963 QWidget *mw =
static_cast<QWidget*>(layout->parent());
964 QCoreApplication::postEvent(mw,
new QEvent(QEvent::LayoutRequest));
967 layout =
static_cast<QLayout*>(layout->parent());
980bool QLayout::activate()
983 if (!d->enabled || !parent())
986 return static_cast<QLayout*>(parent())->activate();
989 QWidget *mw =
static_cast<QWidget*>(parent());
990 if (Q_UNLIKELY(!mw)) {
991 qWarning(
"QLayout::activate: %s \"%ls\" does not have a main widget",
992 metaObject()->className(), qUtf16Printable(objectName()));
995 activateRecursiveHelper(
this);
997 QWidgetPrivate *md = mw->d_func();
998 uint explMin = md->extra ? md->extra->explicitMinSize : 0;
999 uint explMax = md->extra ? md->extra->explicitMaxSize : 0;
1006 QSize minSize(-1, -1);
1007 QSize maxSize(-2, -2);
1010 constexpr QSize empty(0, 0);
1011 QSize totalSzH = empty;
1012 QSize totalMinSz = empty;
1013 QSize totalMaxSz = empty;
1015 switch (d->verticalConstraint) {
1017 totalSzH = totalSizeHint();
1018 minSize.setHeight(totalSzH.height());
1019 maxSize.setHeight(totalSzH.height());
1021 case SetMinimumSize:
1022 totalMinSz = totalMinimumSize();
1023 minSize.setHeight(totalMinSz.height());
1025 case SetMaximumSize:
1026 totalMaxSz = totalMaximumSize();
1027 maxSize.setHeight(totalMaxSz.height());
1029 case SetMinAndMaxSize:
1030 totalMinSz = totalMinimumSize();
1031 totalMaxSz = totalMaximumSize();
1032 minSize.setHeight(totalMinSz.height());
1033 maxSize.setHeight(totalMaxSz.height());
1035 case SetDefaultConstraint: {
1036 bool heightSet = explMin & Qt::Vertical;
1037 if (mw->isWindow()) {
1039 totalMinSz = totalMinimumSize();
1040 minSize.setHeight(totalMinSz.height());
1042 minSize.setHeight(mw->minimumHeight());
1045 minSize.setHeight(heightSet ? mw->minimumHeight() : 0);
1049 case SetNoConstraint:
1052 switch (d->horizontalConstraint) {
1054 if (totalSzH == empty)
1055 totalSzH = totalSizeHint();
1056 minSize.setWidth(totalSzH.width());
1057 maxSize.setWidth(totalSzH.width());
1059 case SetMinimumSize:
1060 if (totalMinSz == empty)
1061 totalMinSz = totalMinimumSize();
1062 minSize.setWidth(totalMinSz.width());
1064 case SetMaximumSize:
1065 if (totalMaxSz == empty)
1066 totalMaxSz = totalMaximumSize();
1067 maxSize.setWidth(totalMaxSz.width());
1069 case SetMinAndMaxSize:
1070 if (totalMinSz == empty)
1071 totalMinSz = totalMinimumSize();
1072 if (totalMaxSz == empty)
1073 totalMaxSz = totalMaximumSize();
1075 minSize.setWidth(totalMinSz.width());
1076 maxSize.setWidth(totalMaxSz.width());
1078 case SetDefaultConstraint: {
1079 const bool widthSet = explMin & Qt::Horizontal;
1080 if (mw->isWindow()) {
1082 if (totalMinSz == empty)
1083 totalMinSz = totalMinimumSize();
1084 minSize.setWidth(totalMinSz.width());
1086 minSize.setWidth(mw->minimumWidth());
1089 minSize.setWidth(widthSet ? mw->minimumWidth() : 0);
1093 case SetNoConstraint:
1096 if (minSize == maxSize) {
1097 mw->setFixedSize(minSize);
1108 if (minSize.isValid())
1109 mw->setMinimumSize(minSize);
1110 else if (minSize.width() >= 0)
1111 mw->setMinimumWidth(minSize.width());
1112 else if (minSize.height() >= 0)
1113 mw->setMinimumHeight(minSize.height());
1116 if (maxSize.isValid())
1117 mw->setMaximumSize(maxSize);
1118 else if (maxSize.width() >= 0)
1119 mw->setMaximumWidth(maxSize.width());
1120 else if (maxSize.height() >= 0)
1121 mw->setMaximumHeight(maxSize.height());
1127 md->extra->explicitMinSize = explMin;
1128 md->extra->explicitMaxSize = explMax;
1131 mw->updateGeometry();
1159QLayoutItem *QLayout::replaceWidget(QWidget *from, QWidget *to, Qt::FindChildOptions options)
1168 QLayoutItem *item =
nullptr;
1169 for (
int u = 0; u < count(); ++u) {
1174 if (item->widget() == from) {
1179 if (item->layout() && (options & Qt::FindChildrenRecursively)) {
1180 QLayoutItem *r = item->layout()->replaceWidget(from, to, options);
1189 QLayoutItem *newitem =
new QWidgetItem(to);
1190 newitem->setAlignment(item->alignment());
1191 QLayoutItem *r = d->replaceAt(index, newitem);