279 QFormLayout::RowWrapPolicy wrapPolicy = q->rowWrapPolicy();
280 bool wrapAllRows = (wrapPolicy == QFormLayout::WrapAllRows);
281 bool dontWrapRows = (wrapPolicy == QFormLayout::DontWrapRows);
282 int rr = m_matrix.rowCount();
288 bool expandH =
false;
289 bool expandV =
false;
294 QWidget *parent = q->parentWidget();
295 QStyle *style = parent ? parent->style() :
nullptr;
297 int userVSpacing = q->verticalSpacing();
298 int userHSpacing = wrapAllRows ? 0 : q->horizontalSpacing();
300 int maxMinLblWidth = 0;
301 int maxMinFldWidth = 0;
302 int maxMinIfldWidth = 0;
304 int maxShLblWidth = 0;
305 int maxShFldWidth = 0;
306 int maxShIfldWidth = 0;
308 for (
int i = 0; i < rr; ++i) {
313 if (!label && !field)
317 updateFormLayoutItem(label, userVSpacing, q->fieldGrowthPolicy(),
false);
320 Qt::Orientations o = label->expandingDirections();
322 if (o & Qt::Vertical)
324 if (o & Qt::Horizontal)
328 updateFormLayoutItem(field, userVSpacing, q->fieldGrowthPolicy(), !label && field->fullRow);
333 Qt::Orientations o = field->expandingDirections();
335 if (o & Qt::Vertical)
337 if (o & Qt::Horizontal)
342 if ((userHSpacing < 0 || userVSpacing < 0) && style) {
343 QSizePolicy::ControlTypes lbltypes =
344 QSizePolicy::ControlTypes(label ? label->controlTypes() : QSizePolicy::DefaultType);
345 QSizePolicy::ControlTypes fldtypes =
346 QSizePolicy::ControlTypes(field ? field->controlTypes() : QSizePolicy::DefaultType);
349 if (userVSpacing < 0) {
355 QSizePolicy::ControlTypes lbltoptypes =
356 QSizePolicy::ControlTypes(lbltop ? lbltop->controlTypes() : QSizePolicy::DefaultType);
357 QSizePolicy::ControlTypes fldtoptypes =
358 QSizePolicy::ControlTypes(fldtop ? fldtop->controlTypes() : QSizePolicy::DefaultType);
360 label->vSpace = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical,
nullptr, parent);
362 field->vSpace = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical,
nullptr, parent);
368 QSizePolicy::ControlTypes lbltoptypes =
369 QSizePolicy::ControlTypes(lbltop ? lbltop->controlTypes() : QSizePolicy::DefaultType);
370 QSizePolicy::ControlTypes fldtoptypes =
371 QSizePolicy::ControlTypes(fldtop ? fldtop->controlTypes() : QSizePolicy::DefaultType);
376 int lblspacing = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical,
nullptr, parent);
377 int fldspacing = style->combinedLayoutSpacing(fldtoptypes, lbltypes, Qt::Vertical,
nullptr, parent);
378 label
->vSpace = qMax(lblspacing, fldspacing);
380 label->vSpace = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical,
nullptr, parent);
387 int lblspacing = style->combinedLayoutSpacing(lbltoptypes, fldtypes, Qt::Vertical,
nullptr, parent);
388 int fldspacing = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical,
nullptr, parent);
389 field
->vSpace = qMax(lblspacing, fldspacing);
391 field->vSpace = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical,
nullptr, parent);
400 if (userHSpacing < 0 && !wrapAllRows && (label || !field->fullRow) && field)
401 field->sbsHSpace = style->combinedLayoutSpacing(QSizePolicy::Label, QSizePolicy::LineEdit, Qt::Horizontal,
nullptr, parent);
412 maxMinLblWidth = qMax(maxMinLblWidth, label->minSize.width());
413 maxShLblWidth = qMax(maxShLblWidth, label->sizeHint.width());
417 maxMinIfldWidth = qMax(maxMinIfldWidth, field->minSize.width());
418 maxShIfldWidth = qMax(maxShIfldWidth, field->sizeHint.width());
420 maxMinFldWidth = qMax(maxMinFldWidth, field->minSize.width() + field
->sbsHSpace);
421 maxShFldWidth = qMax(maxShFldWidth, field->sizeHint.width() + field
->sbsHSpace);
431 sh_width = qMax(maxShLblWidth, qMax(maxShIfldWidth, maxShFldWidth));
432 min_width = qMax(maxMinLblWidth, qMax(maxMinIfldWidth, maxMinFldWidth));
435 }
else if (dontWrapRows) {
437 sh_width = qMax(maxShLblWidth + maxShFldWidth, maxShIfldWidth);
438 min_width = qMax(maxMinLblWidth + maxMinFldWidth, maxMinIfldWidth);
442 sh_width = qMax(maxShLblWidth + maxShFldWidth, maxShIfldWidth);
445 min_width = qMax(maxMinLblWidth, qMax(maxMinIfldWidth, maxMinFldWidth));
447 thresh_width = maxShLblWidth + maxMinFldWidth;
495 int rr = m_matrix.rowCount();
498 hfwLayouts.resize(vLayoutCount);
499 for (i = 0; i < vLayoutCount; ++i)
500 hfwLayouts[i] = vLayouts.at(i);
502 for (i = 0; i < rr; ++i) {
507 if (!q->isRowVisible(i))
515 hfwLayouts[label->vLayoutIndex].minimumSize = hfw;
516 hfwLayouts[label->vLayoutIndex].sizeHint = hfw;
520 hfwLayouts[label->vLayoutIndex].sizeHint = label->sizeHint.height();
521 hfwLayouts[label->vLayoutIndex].minimumSize = label->minSize.height();
527 int h = field
->isHfw ? hfw : field->sizeHint.height();
528 int mh = field
->isHfw ? hfw : field->minSize.height();
531 int oh = hfwLayouts.at(field->vLayoutIndex).sizeHint;
532 int omh = hfwLayouts.at(field->vLayoutIndex).minimumSize;
534 hfwLayouts[field->vLayoutIndex].sizeHint = qMax(h, oh);
535 hfwLayouts[field->vLayoutIndex].minimumSize = qMax(mh, omh);
537 hfwLayouts[field->vLayoutIndex].sizeHint = h;
538 hfwLayouts[field->vLayoutIndex].minimumSize = mh;
582static inline int spacingHelper(QWidget* parent, QStyle *style,
int userVSpacing,
bool recalculate, QFormLayoutItem* item1, QFormLayoutItem* item2, QFormLayoutItem* prevItem1, QFormLayoutItem *prevItem2)
584 int spacing = userVSpacing;
588 spacing = item1->vSpace;
590 spacing = qMax(spacing, item2->vSpace);
592 if (style && prevItem1) {
593 QSizePolicy::ControlTypes itemtypes =
594 QSizePolicy::ControlTypes(item1 ? item1->controlTypes() : QSizePolicy::DefaultType);
597 spacing = style->combinedLayoutSpacing(itemtypes, prevItem1->controlTypes(), Qt::Vertical,
nullptr, parent);
601 spacing2 = style->combinedLayoutSpacing(item2->controlTypes(), prevItem1->controlTypes(), Qt::Vertical,
nullptr, parent);
603 spacing2 = style->combinedLayoutSpacing(itemtypes, prevItem2->controlTypes(), Qt::Vertical,
nullptr, parent);
605 spacing = qMax(spacing, spacing2);
610 QWidget *wid = prevItem1->item->widget();
612 spacing = qMax(spacing, prevItem1->geometry().top() - wid->geometry().top() );
615 QWidget *wid = prevItem2->item->widget();
617 spacing = qMax(spacing, prevItem2->geometry().top() - wid->geometry().top() );
620 return qMax(spacing, 0);
637 if ((width == layoutWidth || (width >= thresh_width && layoutWidth >= thresh_width)) && !dirty && !sizesDirty)
642 int rr = m_matrix.rowCount();
644 QFormLayout::RowWrapPolicy rowWrapPolicy = q->rowWrapPolicy();
645 bool wrapAllRows = (rowWrapPolicy == QFormLayout::WrapAllRows);
646 bool addTopBottomStretch =
true;
649 vLayouts.resize((2 * rr) + 2);
651 QStyle *style =
nullptr;
653 int userVSpacing = q->verticalSpacing();
655 if (userVSpacing < 0) {
656 if (QWidget *widget = q->parentWidget())
657 style = widget->style();
669 for (
int i = 0; i < rr; ++i) {
672 if (label && (label->sizeHint.width() + (field ? field->minSize.width() : 0) <= width))
681 bool prevRowSplit =
false;
683 for (
int i = 0; i < rr; ++i) {
689 if (!q->isRowVisible(i)) {
702 min1 = label->minSize;
703 sh1 = label->sizeHint;
706 min2 = field->minSize;
707 sh2 = field->sizeHint;
712 bool splitSideBySide = (rowWrapPolicy == QFormLayout::WrapLongRows)
713 && ((maxLabelWidth < sh1.width()) || (width < (maxLabelWidth + min2.width())));
715 if (wrapAllRows || splitSideBySide) {
717 initLayoutStruct(vLayouts[vidx], label);
720 vLayouts[vidx - 1].spacing = spacingHelper(q->parentWidget(), style, userVSpacing, splitSideBySide || prevRowSplit, label,
nullptr, prevItem1, prevItem2);
728 if (vLayouts[vidx].stretch > 0)
729 addTopBottomStretch =
false;
735 initLayoutStruct(vLayouts[vidx], field);
738 vLayouts[vidx - 1].spacing = spacingHelper(q->parentWidget(), style, userVSpacing, splitSideBySide || prevRowSplit, field,
nullptr, prevItem1, prevItem2);
746 if (vLayouts[vidx].stretch > 0)
747 addTopBottomStretch =
false;
752 prevRowSplit = splitSideBySide;
760 bool expanding =
false;
763 max1 = label->maxSize;
764 if (label->expandingDirections() & Qt::Vertical)
773 max2 = field->maxSize;
774 if (field->expandingDirections() & Qt::Vertical)
782 vLayouts[vidx].init(qMax(stretch1, stretch2), qMax(min1.height(), min2.height()));
783 vLayouts[vidx].sizeHint = qMax(sh1.height(), sh2.height());
784 vLayouts[vidx].maximumSize = qMin(max1.height(), max2.height());
785 vLayouts[vidx].expansive = expanding || (vLayouts[vidx].stretch > 0);
786 vLayouts[vidx].empty =
false;
788 if (vLayouts[vidx].expansive)
789 addTopBottomStretch =
false;
792 vLayouts[vidx - 1].spacing = spacingHelper(q->parentWidget(), style, userVSpacing, prevRowSplit, label, field, prevItem1, prevItem2);
802 prevRowSplit =
false;
807 if (addTopBottomStretch) {
808 Qt::Alignment formAlignment = q->formAlignment();
810 if (!(formAlignment & Qt::AlignBottom)) {
812 vLayouts[vidx].init(1, 0);
813 vLayouts[vidx].expansive =
true;
817 if (formAlignment & (Qt::AlignVCenter | Qt::AlignBottom)) {
819 vLayouts[0].init(1, 0);
820 vLayouts[0].expansive =
true;
822 vLayouts[0].init(0, 0);
825 vLayouts[0].init(0, 0);
890 int leftMargin, topMargin, rightMargin, bottomMargin;
891 q->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
894 setupVerticalLayoutData(QLAYOUTSIZE_MAX);
897 int h = topMargin + bottomMargin;
898 int mh = topMargin + bottomMargin;
901 int w =
sh_width + leftMargin + rightMargin;
902 int mw =
min_width + leftMargin + rightMargin;
905 int spacing = vLayouts.at(i).spacing;
906 h += vLayouts.at(i).sizeHint + spacing;
907 mh += vLayouts.at(i).minimumSize + spacing;
910 minSize.rwidth() = qMin(mw, QLAYOUTSIZE_MAX);
911 minSize.rheight() = qMin(mh, QLAYOUTSIZE_MAX);
912 prefSize.rwidth() = qMin(w, QLAYOUTSIZE_MAX);
913 prefSize.rheight() = qMin(h, QLAYOUTSIZE_MAX);
1672QLayoutItem *QFormLayout::takeAt(
int index)
1676 const int storageIndex = storageIndexFromLayoutItem(d->m_matrix, d->m_things.value(index));
1677 if (Q_UNLIKELY(storageIndex == -1)) {
1678 qWarning(
"QFormLayout::takeAt: Invalid index %d", index);
1683 QFormLayoutPrivate::ItemMatrix::storageIndexToPosition(storageIndex, &row, &col);
1684 Q_ASSERT(d->m_matrix(row, col));
1686 QFormLayoutItem *item = d->m_matrix(row, col);
1688 d->m_things.removeAt(index);
1689 d->m_matrix(row, col) = 0;
1693 return ownershipCleanedItem(item,
this);
1727int QFormLayout::heightForWidth(
int width)
const
1729 Q_D(
const QFormLayout);
1730 if (!hasHeightForWidth())
1733 int leftMargin, topMargin, rightMargin, bottomMargin;
1734 getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
1736 int targetWidth = width - leftMargin - rightMargin;
1738 if (!d->haveHfwCached(targetWidth)) {
1739 QFormLayoutPrivate *dat =
const_cast<QFormLayoutPrivate *>(d);
1740 dat->setupVerticalLayoutData(targetWidth);
1741 dat->setupHorizontalLayoutData(targetWidth);
1742 dat->recalcHFW(targetWidth);
1744 if (targetWidth == d->sh_width)
1745 return d->hfw_sh_height + topMargin + bottomMargin;
1747 return d->hfw_height + topMargin + bottomMargin;
1753void QFormLayout::setGeometry(
const QRect &rect)
1756 if (d->dirty || rect != geometry()) {
1758 int leftMargin, topMargin, rightMargin, bottomMargin;
1759 getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
1760 cr.adjust(+leftMargin, +topMargin, -rightMargin, -bottomMargin);
1762 bool hfw = hasHeightForWidth();
1763 d->setupVerticalLayoutData(cr.width());
1764 d->setupHorizontalLayoutData(cr.width());
1765 if (hfw && (!d->haveHfwCached(cr.width()) || d->hfwLayouts.size() != d->vLayoutCount))
1766 d->recalcHFW(cr.width());
1768 qGeomCalc(d->hfwLayouts, 0, d->vLayoutCount, cr.y(), cr.height());
1769 d->arrangeWidgets(d->hfwLayouts, cr);
1771 qGeomCalc(d->vLayouts, 0, d->vLayoutCount, cr.y(), cr.height());
1772 d->arrangeWidgets(d->vLayouts, cr);
1774 QLayout::setGeometry(rect);
2185 const int rr = m_matrix.rowCount();
2186 QWidget *w = q->parentWidget();
2187 Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : QGuiApplication::layoutDirection();
2189 Qt::Alignment formAlignment = fixedAlignment(q->formAlignment(), layoutDirection);
2192 if (formAlignment & (Qt::AlignHCenter | Qt::AlignRight) && delta > 0) {
2194 if (formAlignment & Qt::AlignHCenter)
2198 for (i = 0; i < rr; ++i) {
2202 if (!q->isRowVisible(i))
2207 if ((label->expandingDirections() & Qt::Vertical) == 0) {
2209
2210
2211
2212
2213
2214 height = qMin(height,
2215 qMin(label->sizeHint.height() * 7 / 4,
2216 label->maxSize.height()));
2221 const auto fAlign = fixedAlignment(q->labelAlignment(), layoutDirection);
2222 if (fAlign & Qt::AlignRight)
2223 x += label->layoutWidth - sz.width();
2224 else if (fAlign & Qt::AlignHCenter)
2225 x += label->layoutWidth / 2 - sz.width() / 2;
2229 label->setGeometry(QStyle::visualRect(layoutDirection, rect, QRect(p, sz)));
2236
2237
2238
2239
2240
2241 if (field->maxSize.isValid())
2242 sz = sz.boundedTo(field->maxSize);
2244 field->setGeometry(QStyle::visualRect(layoutDirection, rect, QRect(p, sz)));