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);
777bool QLayoutPrivate::checkWidget(QWidget *widget)
const
780 if (Q_UNLIKELY(!widget)) {
781 qWarning(
"QLayout: Cannot add a null widget to %s/%ls", q->metaObject()->className(),
782 qUtf16Printable(q->objectName()));
785 if (Q_UNLIKELY(widget == q->parentWidget())) {
786 qWarning(
"QLayout: Cannot add parent widget %s/%ls to its child layout %s/%ls",
787 widget->metaObject()->className(), qUtf16Printable(widget->objectName()),
788 q->metaObject()->className(), qUtf16Printable(q->objectName()));
823void QLayout::addChildWidget(QWidget *w)
825 QWidget *mw = parentWidget();
826 QWidget *pw = w->parentWidget();
830 if (pw && w->testAttribute(Qt::WA_LaidOut)) {
831 QLayout *l = pw->layout();
832 if (l && removeWidgetRecursively(l, w)) {
834 if (Q_UNLIKELY(layoutDebug()))
835 qWarning(
"QLayout::addChildWidget: %s \"%ls\" is already in a layout; moved to new layout",
836 w->metaObject()->className(), qUtf16Printable(w->objectName()));
840 if (pw && mw && pw != mw) {
842 if (Q_UNLIKELY(layoutDebug()))
843 qWarning(
"QLayout::addChildWidget: %s \"%ls\" in wrong parent; moved to correct parent",
844 w->metaObject()->className(), qUtf16Printable(w->objectName()));
848 bool needShow = mw && mw->isVisible() && !QWidgetPrivate::get(w)->isExplicitlyHidden();
851 w->setAttribute(Qt::WA_LaidOut);
853 QMetaObject::invokeMethod(w,
"_q_showIfNotHidden", Qt::QueuedConnection);
950void QLayout::update()
952 QLayout *layout =
this;
953 while (layout && layout->d_func()->activated) {
954 layout->d_func()->activated =
false;
955 if (layout->d_func()->topLevel) {
956 Q_ASSERT(layout->parent()->isWidgetType());
957 QWidget *mw =
static_cast<QWidget*>(layout->parent());
958 QCoreApplication::postEvent(mw,
new QEvent(QEvent::LayoutRequest));
961 layout =
static_cast<QLayout*>(layout->parent());
974bool QLayout::activate()
977 if (!d->enabled || !parent())
980 return static_cast<QLayout*>(parent())->activate();
983 QWidget *mw =
static_cast<QWidget*>(parent());
984 if (Q_UNLIKELY(!mw)) {
985 qWarning(
"QLayout::activate: %s \"%ls\" does not have a main widget",
986 metaObject()->className(), qUtf16Printable(objectName()));
989 activateRecursiveHelper(
this);
991 QWidgetPrivate *md = mw->d_func();
992 uint explMin = md->extra ? md->extra->explicitMinSize : 0;
993 uint explMax = md->extra ? md->extra->explicitMaxSize : 0;
1000 QSize minSize(-1, -1);
1001 QSize maxSize(-2, -2);
1004 constexpr QSize empty(0, 0);
1005 QSize totalSzH = empty;
1006 QSize totalMinSz = empty;
1007 QSize totalMaxSz = empty;
1009 switch (d->verticalConstraint) {
1011 totalSzH = totalSizeHint();
1012 minSize.setHeight(totalSzH.height());
1013 maxSize.setHeight(totalSzH.height());
1015 case SetMinimumSize:
1016 totalMinSz = totalMinimumSize();
1017 minSize.setHeight(totalMinSz.height());
1019 case SetMaximumSize:
1020 totalMaxSz = totalMaximumSize();
1021 maxSize.setHeight(totalMaxSz.height());
1023 case SetMinAndMaxSize:
1024 totalMinSz = totalMinimumSize();
1025 totalMaxSz = totalMaximumSize();
1026 minSize.setHeight(totalMinSz.height());
1027 maxSize.setHeight(totalMaxSz.height());
1029 case SetDefaultConstraint: {
1030 bool heightSet = explMin & Qt::Vertical;
1031 if (mw->isWindow()) {
1033 totalMinSz = totalMinimumSize();
1034 minSize.setHeight(totalMinSz.height());
1036 minSize.setHeight(mw->minimumHeight());
1039 minSize.setHeight(heightSet ? mw->minimumHeight() : 0);
1043 case SetNoConstraint:
1046 switch (d->horizontalConstraint) {
1048 if (totalSzH == empty)
1049 totalSzH = totalSizeHint();
1050 minSize.setWidth(totalSzH.width());
1051 maxSize.setWidth(totalSzH.width());
1053 case SetMinimumSize:
1054 if (totalMinSz == empty)
1055 totalMinSz = totalMinimumSize();
1056 minSize.setWidth(totalMinSz.width());
1058 case SetMaximumSize:
1059 if (totalMaxSz == empty)
1060 totalMaxSz = totalMaximumSize();
1061 maxSize.setWidth(totalMaxSz.width());
1063 case SetMinAndMaxSize:
1064 if (totalMinSz == empty)
1065 totalMinSz = totalMinimumSize();
1066 if (totalMaxSz == empty)
1067 totalMaxSz = totalMaximumSize();
1069 minSize.setWidth(totalMinSz.width());
1070 maxSize.setWidth(totalMaxSz.width());
1072 case SetDefaultConstraint: {
1073 const bool widthSet = explMin & Qt::Horizontal;
1074 if (mw->isWindow()) {
1076 if (totalMinSz == empty)
1077 totalMinSz = totalMinimumSize();
1078 minSize.setWidth(totalMinSz.width());
1080 minSize.setWidth(mw->minimumWidth());
1083 minSize.setWidth(widthSet ? mw->minimumWidth() : 0);
1087 case SetNoConstraint:
1090 if (minSize == maxSize) {
1091 mw->setFixedSize(minSize);
1102 if (minSize.isValid())
1103 mw->setMinimumSize(minSize);
1104 else if (minSize.width() >= 0)
1105 mw->setMinimumWidth(minSize.width());
1106 else if (minSize.height() >= 0)
1107 mw->setMinimumHeight(minSize.height());
1110 if (maxSize.isValid())
1111 mw->setMaximumSize(maxSize);
1112 else if (maxSize.width() >= 0)
1113 mw->setMaximumWidth(maxSize.width());
1114 else if (maxSize.height() >= 0)
1115 mw->setMaximumHeight(maxSize.height());
1121 md->extra->explicitMinSize = explMin;
1122 md->extra->explicitMaxSize = explMax;
1125 mw->updateGeometry();
1153QLayoutItem *QLayout::replaceWidget(QWidget *from, QWidget *to, Qt::FindChildOptions options)
1162 QLayoutItem *item =
nullptr;
1163 for (
int u = 0; u < count(); ++u) {
1168 if (item->widget() == from) {
1173 if (item->layout() && (options & Qt::FindChildrenRecursively)) {
1174 QLayoutItem *r = item->layout()->replaceWidget(from, to, options);
1183 QLayoutItem *newitem =
new QWidgetItem(to);
1184 newitem->setAlignment(item->alignment());
1185 QLayoutItem *r = d->replaceAt(index, newitem);