280 QFormLayout::RowWrapPolicy wrapPolicy = q->rowWrapPolicy();
281 bool wrapAllRows = (wrapPolicy == QFormLayout::WrapAllRows);
282 bool dontWrapRows = (wrapPolicy == QFormLayout::DontWrapRows);
283 int rr = m_matrix.rowCount();
289 bool expandH =
false;
290 bool expandV =
false;
295 QWidget *parent = q->parentWidget();
296 QStyle *style = parent ? parent->style() :
nullptr;
298 int userVSpacing = q->verticalSpacing();
299 int userHSpacing = wrapAllRows ? 0 : q->horizontalSpacing();
301 int maxMinLblWidth = 0;
302 int maxMinFldWidth = 0;
303 int maxMinIfldWidth = 0;
305 int maxShLblWidth = 0;
306 int maxShFldWidth = 0;
307 int maxShIfldWidth = 0;
309 for (
int i = 0; i < rr; ++i) {
314 if (!label && !field)
318 updateFormLayoutItem(label, userVSpacing, q->fieldGrowthPolicy(),
false);
321 Qt::Orientations o = label->expandingDirections();
323 if (o & Qt::Vertical)
325 if (o & Qt::Horizontal)
329 updateFormLayoutItem(field, userVSpacing, q->fieldGrowthPolicy(), !label && field->fullRow);
334 Qt::Orientations o = field->expandingDirections();
336 if (o & Qt::Vertical)
338 if (o & Qt::Horizontal)
343 if ((userHSpacing < 0 || userVSpacing < 0) && style) {
344 QSizePolicy::ControlTypes lbltypes =
345 QSizePolicy::ControlTypes(label ? label->controlTypes() : QSizePolicy::DefaultType);
346 QSizePolicy::ControlTypes fldtypes =
347 QSizePolicy::ControlTypes(field ? field->controlTypes() : QSizePolicy::DefaultType);
350 if (userVSpacing < 0) {
356 QSizePolicy::ControlTypes lbltoptypes =
357 QSizePolicy::ControlTypes(lbltop ? lbltop->controlTypes() : QSizePolicy::DefaultType);
358 QSizePolicy::ControlTypes fldtoptypes =
359 QSizePolicy::ControlTypes(fldtop ? fldtop->controlTypes() : QSizePolicy::DefaultType);
361 label->vSpace = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical,
nullptr, parent);
363 field->vSpace = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical,
nullptr, parent);
369 QSizePolicy::ControlTypes lbltoptypes =
370 QSizePolicy::ControlTypes(lbltop ? lbltop->controlTypes() : QSizePolicy::DefaultType);
371 QSizePolicy::ControlTypes fldtoptypes =
372 QSizePolicy::ControlTypes(fldtop ? fldtop->controlTypes() : QSizePolicy::DefaultType);
377 int lblspacing = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical,
nullptr, parent);
378 int fldspacing = style->combinedLayoutSpacing(fldtoptypes, lbltypes, Qt::Vertical,
nullptr, parent);
379 label
->vSpace = qMax(lblspacing, fldspacing);
381 label->vSpace = style->combinedLayoutSpacing(lbltoptypes, lbltypes, Qt::Vertical,
nullptr, parent);
388 int lblspacing = style->combinedLayoutSpacing(lbltoptypes, fldtypes, Qt::Vertical,
nullptr, parent);
389 int fldspacing = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical,
nullptr, parent);
390 field
->vSpace = qMax(lblspacing, fldspacing);
392 field->vSpace = style->combinedLayoutSpacing(fldtoptypes, fldtypes, Qt::Vertical,
nullptr, parent);
401 if (userHSpacing < 0 && !wrapAllRows && (label || !field->fullRow) && field)
402 field->sbsHSpace = style->combinedLayoutSpacing(QSizePolicy::Label, QSizePolicy::LineEdit, Qt::Horizontal,
nullptr, parent);
413 maxMinLblWidth = qMax(maxMinLblWidth, label->minSize.width());
414 maxShLblWidth = qMax(maxShLblWidth, label->sizeHint.width());
418 maxMinIfldWidth = qMax(maxMinIfldWidth, field->minSize.width());
419 maxShIfldWidth = qMax(maxShIfldWidth, field->sizeHint.width());
421 maxMinFldWidth = qMax(maxMinFldWidth, field->minSize.width() + field
->sbsHSpace);
422 maxShFldWidth = qMax(maxShFldWidth, field->sizeHint.width() + field
->sbsHSpace);
432 sh_width = qMax(maxShLblWidth, qMax(maxShIfldWidth, maxShFldWidth));
433 min_width = qMax(maxMinLblWidth, qMax(maxMinIfldWidth, maxMinFldWidth));
436 }
else if (dontWrapRows) {
438 sh_width = qMax(maxShLblWidth + maxShFldWidth, maxShIfldWidth);
439 min_width = qMax(maxMinLblWidth + maxMinFldWidth, maxMinIfldWidth);
443 sh_width = qMax(maxShLblWidth + maxShFldWidth, maxShIfldWidth);
446 min_width = qMax(maxMinLblWidth, qMax(maxMinIfldWidth, maxMinFldWidth));
448 thresh_width = maxShLblWidth + maxMinFldWidth;
496 int rr = m_matrix.rowCount();
499 hfwLayouts.resize(vLayoutCount);
500 for (i = 0; i < vLayoutCount; ++i)
501 hfwLayouts[i] = vLayouts.at(i);
503 for (i = 0; i < rr; ++i) {
508 if (!q->isRowVisible(i))
516 hfwLayouts[label->vLayoutIndex].minimumSize = hfw;
517 hfwLayouts[label->vLayoutIndex].sizeHint = hfw;
521 hfwLayouts[label->vLayoutIndex].sizeHint = label->sizeHint.height();
522 hfwLayouts[label->vLayoutIndex].minimumSize = label->minSize.height();
528 int h = field
->isHfw ? hfw : field->sizeHint.height();
529 int mh = field
->isHfw ? hfw : field->minSize.height();
532 int oh = hfwLayouts.at(field->vLayoutIndex).sizeHint;
533 int omh = hfwLayouts.at(field->vLayoutIndex).minimumSize;
535 hfwLayouts[field->vLayoutIndex].sizeHint = qMax(h, oh);
536 hfwLayouts[field->vLayoutIndex].minimumSize = qMax(mh, omh);
538 hfwLayouts[field->vLayoutIndex].sizeHint = h;
539 hfwLayouts[field->vLayoutIndex].minimumSize = mh;
583static inline int spacingHelper(QWidget* parent, QStyle *style,
int userVSpacing,
bool recalculate, QFormLayoutItem* item1, QFormLayoutItem* item2, QFormLayoutItem* prevItem1, QFormLayoutItem *prevItem2)
585 int spacing = userVSpacing;
589 spacing = item1->vSpace;
591 spacing = qMax(spacing, item2->vSpace);
593 if (style && prevItem1) {
594 QSizePolicy::ControlTypes itemtypes =
595 QSizePolicy::ControlTypes(item1 ? item1->controlTypes() : QSizePolicy::DefaultType);
598 spacing = style->combinedLayoutSpacing(itemtypes, prevItem1->controlTypes(), Qt::Vertical,
nullptr, parent);
602 spacing2 = style->combinedLayoutSpacing(item2->controlTypes(), prevItem1->controlTypes(), Qt::Vertical,
nullptr, parent);
604 spacing2 = style->combinedLayoutSpacing(itemtypes, prevItem2->controlTypes(), Qt::Vertical,
nullptr, parent);
606 spacing = qMax(spacing, spacing2);
611 QWidget *wid = prevItem1->item->widget();
613 spacing = qMax(spacing, prevItem1->geometry().top() - wid->geometry().top() );
616 QWidget *wid = prevItem2->item->widget();
618 spacing = qMax(spacing, prevItem2->geometry().top() - wid->geometry().top() );
621 return qMax(spacing, 0);
638 if ((width == layoutWidth || (width >= thresh_width && layoutWidth >= thresh_width)) && !dirty && !sizesDirty)
643 int rr = m_matrix.rowCount();
645 QFormLayout::RowWrapPolicy rowWrapPolicy = q->rowWrapPolicy();
646 bool wrapAllRows = (rowWrapPolicy == QFormLayout::WrapAllRows);
647 bool addTopBottomStretch =
true;
650 vLayouts.resize((2 * rr) + 2);
652 QStyle *style =
nullptr;
654 int userVSpacing = q->verticalSpacing();
656 if (userVSpacing < 0) {
657 if (QWidget *widget = q->parentWidget())
658 style = widget->style();
670 for (
int i = 0; i < rr; ++i) {
673 if (label && (label->sizeHint.width() + (field ? field->minSize.width() : 0) <= width))
682 bool prevRowSplit =
false;
684 for (
int i = 0; i < rr; ++i) {
690 if (!q->isRowVisible(i)) {
703 min1 = label->minSize;
704 sh1 = label->sizeHint;
707 min2 = field->minSize;
708 sh2 = field->sizeHint;
713 bool splitSideBySide = (rowWrapPolicy == QFormLayout::WrapLongRows)
714 && ((maxLabelWidth < sh1.width()) || (width < (maxLabelWidth + min2.width())));
716 if (wrapAllRows || splitSideBySide) {
718 initLayoutStruct(vLayouts[vidx], label);
721 vLayouts[vidx - 1].spacing = spacingHelper(q->parentWidget(), style, userVSpacing, splitSideBySide || prevRowSplit, label,
nullptr, prevItem1, prevItem2);
729 if (vLayouts[vidx].stretch > 0)
730 addTopBottomStretch =
false;
736 initLayoutStruct(vLayouts[vidx], field);
739 vLayouts[vidx - 1].spacing = spacingHelper(q->parentWidget(), style, userVSpacing, splitSideBySide || prevRowSplit, field,
nullptr, prevItem1, prevItem2);
747 if (vLayouts[vidx].stretch > 0)
748 addTopBottomStretch =
false;
753 prevRowSplit = splitSideBySide;
761 bool expanding =
false;
764 max1 = label->maxSize;
765 if (label->expandingDirections() & Qt::Vertical)
774 max2 = field->maxSize;
775 if (field->expandingDirections() & Qt::Vertical)
783 vLayouts[vidx].init(qMax(stretch1, stretch2), qMax(min1.height(), min2.height()));
784 vLayouts[vidx].sizeHint = qMax(sh1.height(), sh2.height());
785 vLayouts[vidx].maximumSize = qMin(max1.height(), max2.height());
786 vLayouts[vidx].expansive = expanding || (vLayouts[vidx].stretch > 0);
787 vLayouts[vidx].empty =
false;
789 if (vLayouts[vidx].expansive)
790 addTopBottomStretch =
false;
793 vLayouts[vidx - 1].spacing = spacingHelper(q->parentWidget(), style, userVSpacing, prevRowSplit, label, field, prevItem1, prevItem2);
803 prevRowSplit =
false;
808 if (addTopBottomStretch) {
809 Qt::Alignment formAlignment = q->formAlignment();
811 if (!(formAlignment & Qt::AlignBottom)) {
813 vLayouts[vidx].init(1, 0);
814 vLayouts[vidx].expansive =
true;
818 if (formAlignment & (Qt::AlignVCenter | Qt::AlignBottom)) {
820 vLayouts[0].init(1, 0);
821 vLayouts[0].expansive =
true;
823 vLayouts[0].init(0, 0);
826 vLayouts[0].init(0, 0);
891 int leftMargin, topMargin, rightMargin, bottomMargin;
892 q->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
895 setupVerticalLayoutData(QLAYOUTSIZE_MAX);
898 int h = topMargin + bottomMargin;
899 int mh = topMargin + bottomMargin;
902 int w =
sh_width + leftMargin + rightMargin;
903 int mw =
min_width + leftMargin + rightMargin;
906 int spacing = vLayouts.at(i).spacing;
907 h += vLayouts.at(i).sizeHint + spacing;
908 mh += vLayouts.at(i).minimumSize + spacing;
911 minSize.rwidth() = qMin(mw, QLAYOUTSIZE_MAX);
912 minSize.rheight() = qMin(mh, QLAYOUTSIZE_MAX);
913 prefSize.rwidth() = qMin(w, QLAYOUTSIZE_MAX);
914 prefSize.rheight() = qMin(h, QLAYOUTSIZE_MAX);
1677QLayoutItem *QFormLayout::takeAt(
int index)
1681 const int storageIndex = storageIndexFromLayoutItem(d->m_matrix, d->m_things.value(index));
1682 if (Q_UNLIKELY(storageIndex == -1)) {
1683 qWarning(
"QFormLayout::takeAt: Invalid index %d", index);
1688 QFormLayoutPrivate::ItemMatrix::storageIndexToPosition(storageIndex, &row, &col);
1689 Q_ASSERT(d->m_matrix(row, col));
1691 QFormLayoutItem *item = d->m_matrix(row, col);
1693 d->m_things.removeAt(index);
1694 d->m_matrix(row, col) = 0;
1698 return ownershipCleanedItem(item,
this);
1732int QFormLayout::heightForWidth(
int width)
const
1734 Q_D(
const QFormLayout);
1735 if (!hasHeightForWidth())
1738 int leftMargin, topMargin, rightMargin, bottomMargin;
1739 getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
1741 int targetWidth = width - leftMargin - rightMargin;
1743 if (!d->haveHfwCached(targetWidth)) {
1744 QFormLayoutPrivate *dat =
const_cast<QFormLayoutPrivate *>(d);
1745 dat->setupVerticalLayoutData(targetWidth);
1746 dat->setupHorizontalLayoutData(targetWidth);
1747 dat->recalcHFW(targetWidth);
1749 if (targetWidth == d->sh_width)
1750 return d->hfw_sh_height + topMargin + bottomMargin;
1752 return d->hfw_height + topMargin + bottomMargin;
1758void QFormLayout::setGeometry(
const QRect &rect)
1761 if (d->dirty || rect != geometry()) {
1763 int leftMargin, topMargin, rightMargin, bottomMargin;
1764 getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
1765 cr.adjust(+leftMargin, +topMargin, -rightMargin, -bottomMargin);
1767 bool hfw = hasHeightForWidth();
1768 d->setupVerticalLayoutData(cr.width());
1769 d->setupHorizontalLayoutData(cr.width());
1770 if (hfw && (!d->haveHfwCached(cr.width()) || d->hfwLayouts.size() != d->vLayoutCount))
1771 d->recalcHFW(cr.width());
1773 qGeomCalc(d->hfwLayouts, 0, d->vLayoutCount, cr.y(), cr.height());
1774 d->arrangeWidgets(d->hfwLayouts, cr);
1776 qGeomCalc(d->vLayouts, 0, d->vLayoutCount, cr.y(), cr.height());
1777 d->arrangeWidgets(d->vLayouts, cr);
1779 QLayout::setGeometry(rect);
2190 const int rr = m_matrix.rowCount();
2191 QWidget *w = q->parentWidget();
2192 Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : QGuiApplication::layoutDirection();
2194 Qt::Alignment formAlignment = fixedAlignment(q->formAlignment(), layoutDirection);
2197 if (formAlignment & (Qt::AlignHCenter | Qt::AlignRight) && delta > 0) {
2199 if (formAlignment & Qt::AlignHCenter)
2203 for (i = 0; i < rr; ++i) {
2207 if (!q->isRowVisible(i))
2212 if ((label->expandingDirections() & Qt::Vertical) == 0) {
2214
2215
2216
2217
2218
2219 height = qMin(height,
2220 qMin(label->sizeHint.height() * 7 / 4,
2221 label->maxSize.height()));
2226 const auto fAlign = fixedAlignment(q->labelAlignment(), layoutDirection);
2227 if (fAlign & Qt::AlignRight)
2228 x += label->layoutWidth - sz.width();
2229 else if (fAlign & Qt::AlignHCenter)
2230 x += label->layoutWidth / 2 - sz.width() / 2;
2234 label->setGeometry(QStyle::visualRect(layoutDirection, rect, QRect(p, sz)));
2241
2242
2243
2244
2245
2246 if (field->maxSize.isValid())
2247 sz = sz.boundedTo(field->maxSize);
2249 field->setGeometry(QStyle::visualRect(layoutDirection, rect, QRect(p, sz)));