Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qlayoutitem.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qlayout.h"
5
6#include "qapplication.h"
7#include "qlayoutengine_p.h"
8#if QT_CONFIG(menubar)
9#include "qmenubar.h"
10#endif
11#if QT_CONFIG(toolbar)
12#include "qtoolbar.h"
13#endif
14#include "qevent.h"
15#include "qstyle.h"
16#include "qvariant.h"
17#include "qwidget_p.h"
18
20
22{
23 return rect.adjusted(priv->leftLayoutItemMargin, priv->topLayoutItemMargin,
24 -priv->rightLayoutItemMargin, -priv->bottomLayoutItemMargin);
25}
26
28{
29 return fromLayoutItemRect(priv, QRect(QPoint(0, 0), size)).size();
30}
31
33{
34 return rect.adjusted(-priv->leftLayoutItemMargin, -priv->topLayoutItemMargin,
35 priv->rightLayoutItemMargin, priv->bottomLayoutItemMargin);
36}
37
39{
40 return toLayoutItemRect(priv, QRect(QPoint(0, 0), size)).size();
41}
42
157{
159}
160
226
242 QSizePolicy::Policy vPolicy)
243{
244 width = w;
245 height = h;
246 sizeP = QSizePolicy(hPolicy, vPolicy);
247}
248
258QWidgetItem::~QWidgetItem() = default;
259
263QLayoutItem::~QLayoutItem() = default;
264
269{
270}
271
279{
280 return nullptr;
281}
282
290{
291 return nullptr;
292}
293
298{
299 return this;
300}
301
306{
307 return this;
308}
309
328{
329 return nullptr;
330}
331
336{
337 return wid;
338}
339
351{
352 return false;
353}
354
361{
362 return heightForWidth(w);
363}
364
365
384int QLayoutItem::heightForWidth(int /* w */) const
385{
386 return -1;
387}
388
397QSizePolicy::ControlTypes QLayoutItem::controlTypes() const
398{
400}
401
406{
407 rect = r;
408}
409
414{
415 if (isEmpty())
416 return;
417
419 ? fromLayoutItemRect(wid->d_func(), rect)
420 : rect;
421 const QSize widgetRectSurplus = r.size() - rect.size();
422
423 /*
424 For historical reasons, this code is done using widget rect
425 coordinates, not layout item rect coordinates. However,
426 QWidgetItem's sizeHint(), maximumSize(), and heightForWidth()
427 all work in terms of layout item rect coordinates, so we have to
428 add or subtract widgetRectSurplus here and there. The code could
429 be much simpler if we did everything using layout item rect
430 coordinates and did the conversion right before the call to
431 QWidget::setGeometry().
432 */
433
434 QSize s = r.size().boundedTo(maximumSize() + widgetRectSurplus);
435 int x = r.x();
436 int y = r.y();
438 QSize pref(sizeHint());
440 if (sp.horizontalPolicy() == QSizePolicy::Ignored)
441 pref.setWidth(wid->sizeHint().expandedTo(wid->minimumSize()).width());
442 if (sp.verticalPolicy() == QSizePolicy::Ignored)
443 pref.setHeight(wid->sizeHint().expandedTo(wid->minimumSize()).height());
444 pref += widgetRectSurplus;
446 s.setWidth(qMin(s.width(), pref.width()));
448 if (hasHeightForWidth())
449 s.setHeight(qMin(s.height(),
450 heightForWidth(s.width() - widgetRectSurplus.width())
451 + widgetRectSurplus.height()));
452 else
453 s.setHeight(qMin(s.height(), pref.height()));
454 }
455 }
456 Qt::Alignment alignHoriz = QStyle::visualAlignment(wid->layoutDirection(), align);
457 if (alignHoriz & Qt::AlignRight)
458 x = x + (r.width() - s.width());
459 else if (!(alignHoriz & Qt::AlignLeft))
460 x = x + (r.width() - s.width()) / 2;
461
463 y = y + (r.height() - s.height());
464 else if (!(align & Qt::AlignTop))
465 y = y + (r.height() - s.height()) / 2;
466
467 // Make sure we don't move outside of the parent, e.g when styles demand
468 // surplus space that exceeds the available margins (f.ex macOS with QGroupBox)
469 if (x < 0) {
470 s.rwidth() += x;
471 x = 0;
472 }
473 if (y < 0) {
474 s.rheight() += y;
475 y = 0;
476 }
477
478 wid->setGeometry(x, y, s.width(), s.height());
479}
480
485{
486 return rect;
487}
488
498
499
504{
505 if (isEmpty())
506 return false;
507 return wid->hasHeightForWidth();
508}
509
514{
515 if (isEmpty())
516 return -1;
517
519 ? fromLayoutItemSize(wid->d_func(), QSize(w, 0)).width()
520 : w;
521
522 int hfw;
523 if (wid->layout())
524 hfw = wid->layout()->totalHeightForWidth(w);
525 else
526 hfw = wid->heightForWidth(w);
527
528 if (hfw > wid->maximumHeight())
529 hfw = wid->maximumHeight();
530 if (hfw < wid->minimumHeight())
531 hfw = wid->minimumHeight();
532
534 ? toLayoutItemSize(wid->d_func(), QSize(0, hfw)).height()
535 : hfw;
536
537 if (hfw < 0)
538 hfw = 0;
539 return hfw;
540}
541
543{
544 if (isEmpty())
545 return -1;
546
548 ? fromLayoutItemSize(wid->d_func(), QSize(w, 0)).width()
549 : w;
550
551 int hfw;
552 if (wid->layout())
554 else
555 hfw = wid->heightForWidth(w); // QWidget doesn't have minimumHeightForWidth()
556
557 if (hfw > wid->maximumHeight())
558 hfw = wid->maximumHeight();
559 if (hfw < wid->minimumHeight())
560 hfw = wid->minimumHeight();
561
563 ? toLayoutItemSize(wid->d_func(), QSize(0, hfw)).height()
564 : hfw;
565
566 if (hfw < 0)
567 hfw = 0;
568 return hfw;
569
570}
571
575Qt::Orientations QSpacerItem::expandingDirections() const
576{
577 return sizeP.expandingDirections();
578}
579
583Qt::Orientations QWidgetItem::expandingDirections() const
584{
585 if (isEmpty())
586 return {};
587
588 Qt::Orientations e = wid->sizePolicy().expandingDirections();
589 /*
590 If the layout is expanding, we make the widget expanding, even if
591 its own size policy isn't expanding.
592 */
593 if (wid->layout()) {
596 e |= Qt::Horizontal;
599 e |= Qt::Vertical;
600 }
601
603 e &= ~Qt::Horizontal;
605 e &= ~Qt::Vertical;
606 return e;
607}
608
617
622{
623 if (isEmpty())
624 return QSize(0, 0);
626 ? toLayoutItemSize(wid->d_func(), qSmartMinSize(this))
627 : qSmartMinSize(this);
628}
629
638
643{
644 if (isEmpty()) {
645 return QSize(0, 0);
646 } else {
648 ? toLayoutItemSize(wid->d_func(), qSmartMaxSize(this, align))
649 : qSmartMaxSize(this, align);
650 }
651}
652
657{
658 return QSize(width, height);
659}
660
665{
666 QSize s(0, 0);
667 if (!isEmpty()) {
669 s = s.boundedTo(wid->maximumSize())
670 .expandedTo(wid->minimumSize());
672 ? toLayoutItemSize(wid->d_func(), s)
673 : s;
674
676 s.setWidth(0);
678 s.setHeight(0);
679 }
680 return s;
681}
682
687{
688 return true;
689}
690
697{
698 return (wid->isHidden() && !wid->sizePolicy().retainSizeWhenHidden()) || wid->isWindow();
699}
700
707QSizePolicy::ControlTypes QWidgetItem::controlTypes() const
708{
709 return wid->sizePolicy().controlType();
710}
711
717inline bool QWidgetItemV2::useSizeCache() const
718{
719 return wid->d_func()->widgetItem == this;
720}
721
722void QWidgetItemV2::updateCacheIfNecessary() const
723{
724 if (q_cachedMinimumSize.width() != Dirty)
725 return;
726
727 const QSize sizeHint(wid->sizeHint());
728 const QSize minimumSizeHint(wid->minimumSizeHint());
732 const QSize expandedSizeHint(sizeHint.expandedTo(minimumSizeHint));
733
734 const QSize smartMinSize(qSmartMinSize(sizeHint, minimumSizeHint, minimumSize, maximumSize, sizePolicy));
735 const QSize smartMaxSize(qSmartMaxSize(expandedSizeHint, minimumSize, maximumSize, sizePolicy, align));
736
737 const bool useLayoutItemRect = !wid->testAttribute(Qt::WA_LayoutUsesWidgetRect);
738
739 q_cachedMinimumSize = useLayoutItemRect
740 ? toLayoutItemSize(wid->d_func(), smartMinSize)
741 : smartMinSize;
742
743 q_cachedSizeHint = expandedSizeHint;
744 q_cachedSizeHint = q_cachedSizeHint.boundedTo(maximumSize)
745 .expandedTo(minimumSize);
746 q_cachedSizeHint = useLayoutItemRect
747 ? toLayoutItemSize(wid->d_func(), q_cachedSizeHint)
748 : q_cachedSizeHint;
749
751 q_cachedSizeHint.setWidth(0);
753 q_cachedSizeHint.setHeight(0);
754
755 q_cachedMaximumSize = useLayoutItemRect
756 ? toLayoutItemSize(wid->d_func(), smartMaxSize)
757 : smartMaxSize;
758}
759
762 q_cachedMinimumSize(Dirty, Dirty),
763 q_cachedSizeHint(Dirty, Dirty),
764 q_cachedMaximumSize(Dirty, Dirty),
765 q_firstCachedHfw(0),
766 q_hfwCacheSize(0),
767 d(nullptr)
768{
769 QWidgetPrivate *wd = wid->d_func();
770 if (!wd->widgetItem)
771 wd->widgetItem = this;
772}
773
775{
776 if (wid) {
777 auto *wd = static_cast<QWidgetPrivate *>(QObjectPrivate::get(wid));
778 if (wd->widgetItem == this)
779 wd->widgetItem = nullptr;
780 }
781}
782
784{
785 if (isEmpty())
786 return QSize(0, 0);
787
788 if (useSizeCache()) {
789 updateCacheIfNecessary();
790 return q_cachedSizeHint;
791 } else {
792 return QWidgetItem::sizeHint();
793 }
794}
795
797{
798 if (isEmpty())
799 return QSize(0, 0);
800
801 if (useSizeCache()) {
802 updateCacheIfNecessary();
803 return q_cachedMinimumSize;
804 } else {
806 }
807}
808
810{
811 if (isEmpty())
812 return QSize(0, 0);
813
814 if (useSizeCache()) {
815 updateCacheIfNecessary();
816 return q_cachedMaximumSize;
817 } else {
819 }
820}
821
822/*
823 The height-for-width cache is organized as a circular buffer. The entries
824
825 q_hfwCachedHfws[q_firstCachedHfw],
826 ...,
827 q_hfwCachedHfws[(q_firstCachedHfw + q_hfwCacheSize - 1) % HfwCacheMaxSize]
828
829 contain the last cached values. When the cache is full, the first entry to
830 be erased is the entry before q_hfwCachedHfws[q_firstCachedHfw]. When
831 values are looked up, we try to move q_firstCachedHfw to point to that new
832 entry (unless the cache is not full, in which case it would leave the cache
833 in a broken state), so that the most recently used entry is also the last
834 to be erased.
835*/
836
838{
839 if (isEmpty())
840 return -1;
841
842 for (int i = 0; i < q_hfwCacheSize; ++i) {
843 int offset = q_firstCachedHfw + i;
844 const QSize &size = q_cachedHfws[offset % HfwCacheMaxSize];
845 if (size.width() == width) {
846 if (q_hfwCacheSize == HfwCacheMaxSize)
847 q_firstCachedHfw = offset % HfwCacheMaxSize;
848 return size.height();
849 }
850 }
851
852 if (q_hfwCacheSize < HfwCacheMaxSize)
853 ++q_hfwCacheSize;
854 q_firstCachedHfw = (q_firstCachedHfw + HfwCacheMaxSize - 1) % HfwCacheMaxSize;
855
857 q_cachedHfws[q_firstCachedHfw] = QSize(width, height);
858 return height;
859}
860
virtual QSizePolicy::ControlTypes controlTypes() const
Returns the control type(s) for the layout item.
virtual bool hasHeightForWidth() const
Returns true if this layout's preferred height depends on its width; otherwise returns false.
virtual int heightForWidth(int) const
Returns the preferred height for this layout item, given the width, which is not used in this default...
virtual QLayout * layout()
If this item is a QLayout, it is returned as a QLayout; otherwise \nullptr is returned.
Qt::Alignment align
Definition qlayoutitem.h:50
virtual ~QLayoutItem()
Destroys the QLayoutItem.
Qt::Alignment alignment() const
Returns the alignment of this item.
Definition qlayoutitem.h:45
virtual QSpacerItem * spacerItem()
If this item is a QSpacerItem, it is returned as a QSpacerItem; otherwise \nullptr is returned.
virtual int minimumHeightForWidth(int) const
Returns the minimum height this widget needs for the given width, w.
virtual QWidget * widget() const
If this item manages a QWidget, returns that widget.
virtual void invalidate()
Invalidates any cached information in this layout item.
void setAlignment(Qt::Alignment a)
Sets the alignment of this item to alignment.
The QLayout class is the base class of geometry managers.
Definition qlayout.h:26
int totalHeightForWidth(int w) const
Definition qlayout.cpp:599
int totalMinimumHeightForWidth(int w) const
Definition qlayout.cpp:577
Qt::Orientations expandingDirections() const override
Returns whether this layout can make use of more space than sizeHint().
Definition qlayout.cpp:944
QLayout * layout() override
\reimp
static QObjectPrivate * get(QObject *o)
Definition qobject_p.h:150
\inmodule QtCore\reentrant
Definition qpoint.h:25
\inmodule QtCore\reentrant
Definition qrect.h:30
The QSizePolicy class is a layout attribute describing horizontal and vertical resizing policy.
Definition qsizepolicy.h:18
constexpr Policy verticalPolicy() const noexcept
Returns the vertical component of the size policy.
Definition qsizepolicy.h:67
ControlType controlType() const noexcept
constexpr bool retainSizeWhenHidden() const noexcept
Definition qsizepolicy.h:97
constexpr Qt::Orientations expandingDirections() const noexcept
Returns whether a widget can make use of more space than the QWidget::sizeHint() function indicates.
Definition qsizepolicy.h:75
constexpr Policy horizontalPolicy() const noexcept
Returns the horizontal component of the size policy.
Definition qsizepolicy.h:66
Policy
This enum describes the various per-dimension sizing types used when constructing a QSizePolicy.
Definition qsizepolicy.h:29
\inmodule QtCore
Definition qsize.h:25
constexpr QSize boundedTo(const QSize &) const noexcept
Returns a size holding the minimum width and height of this size and the given otherSize.
Definition qsize.h:197
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
constexpr QSize expandedTo(const QSize &) const noexcept
Returns a size holding the maximum width and height of this size and the given otherSize.
Definition qsize.h:192
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
Definition qsize.h:136
constexpr void setHeight(int h) noexcept
Sets the height to the given height.
Definition qsize.h:139
The QSpacerItem class provides blank space in a layout.
Definition qlayoutitem.h:57
QSize sizeHint() const override
\reimp
QRect geometry() const override
\reimp
bool isEmpty() const override
Returns true.
QSpacerItem * spacerItem() override
Returns a pointer to this object.
~QSpacerItem()
Destructor.
QSize minimumSize() const override
\reimp
void setGeometry(const QRect &) override
\reimp
Qt::Orientations expandingDirections() const override
\reimp
QSize maximumSize() const override
\reimp
void changeSize(int w, int h, QSizePolicy::Policy hData=QSizePolicy::Minimum, QSizePolicy::Policy vData=QSizePolicy::Minimum)
Changes this spacer item to have preferred width w, preferred height h, horizontal size policy hPolic...
static Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
Transforms an alignment of Qt::AlignLeft or Qt::AlignRight without Qt::AlignAbsolute into Qt::AlignLe...
Definition qstyle.cpp:2202
int heightForWidth(int width) const override
\reimp
QWidgetItemV2(QWidget *widget)
QSize sizeHint() const override
\reimp
QSize minimumSize() const override
\reimp
QSize maximumSize() const override
\reimp
The QWidgetItem class is a layout item that represents a widget.
Definition qlayoutitem.h:86
bool isEmpty() const override
Returns true if the widget is hidden; otherwise returns false.
int minimumHeightForWidth(int) const override
Returns the minimum height this widget needs for the given width, w.
QSize sizeHint() const override
\reimp
QWidget * widget() const override
Returns the widget managed by this item.
void setGeometry(const QRect &) override
\reimp
QSizePolicy::ControlTypes controlTypes() const override
Returns the control type associated with the widget for which this size policy applies.
Qt::Orientations expandingDirections() const override
\reimp
int heightForWidth(int) const override
\reimp
QWidget * wid
QSize maximumSize() const override
\reimp
bool hasHeightForWidth() const override
\reimp
QRect geometry() const override
\reimp
QSize minimumSize() const override
\reimp
~QWidgetItem()
Destructor.
QWidgetItemV2 * widgetItem
Definition qwidget_p.h:654
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
virtual bool hasHeightForWidth() const
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qwidget.h:886
Qt::LayoutDirection layoutDirection
the layout direction for this widget.
Definition qwidget.h:170
int minimumHeight
the widget's minimum height in pixels
Definition qwidget.h:125
bool isHidden() const
Returns true if the widget is hidden, otherwise returns false.
Definition qwidget.h:877
QSize minimumSize
the widget's minimum size
Definition qwidget.h:120
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition qwidget.h:106
QLayout * layout() const
Returns the layout manager that is installed on this widget, or \nullptr if no layout manager is inst...
QSize maximumSize
the widget's maximum size in pixels
Definition qwidget.h:121
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition qwidget.h:119
QSize minimumSizeHint
the recommended minimum size for the widget
Definition qwidget.h:149
int maximumHeight
the widget's maximum height in pixels
Definition qwidget.h:129
QSize sizeHint
the recommended size for the widget
Definition qwidget.h:148
bool isWindow() const
Returns true if the widget is an independent window, otherwise returns false.
Definition qwidget.h:811
bool testAttribute(Qt::WidgetAttribute) const
Returns true if attribute attribute is set on this widget; otherwise returns false.
Definition qwidget.h:910
virtual int heightForWidth(int) const
Returns the preferred height for this widget, given the width w.
QOpenGLWidget * widget
[1]
rect
[4]
uint alignment
Combined button and popup list for selecting options.
Definition qcompare.h:63
@ AlignRight
Definition qnamespace.h:146
@ AlignBottom
Definition qnamespace.h:154
@ AlignTop
Definition qnamespace.h:153
@ AlignHorizontal_Mask
Definition qnamespace.h:151
@ AlignVertical_Mask
Definition qnamespace.h:161
@ AlignLeft
Definition qnamespace.h:144
@ WA_LayoutUsesWidgetRect
Definition qnamespace.h:365
@ Horizontal
Definition qnamespace.h:99
@ Vertical
Definition qnamespace.h:100
QLatin1StringView sizePolicy(int v)
Definition language.cpp:124
Q_WIDGETS_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy)
Q_WIDGETS_EXPORT QSize qSmartMaxSize(const QSize &sizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy, Qt::Alignment align)
static QSize toLayoutItemSize(QWidgetPrivate *priv, const QSize &size)
static QT_BEGIN_NAMESPACE QRect fromLayoutItemRect(QWidgetPrivate *priv, const QRect &rect)
static QRect toLayoutItemRect(QWidgetPrivate *priv, const QRect &rect)
static QSize fromLayoutItemSize(QWidgetPrivate *priv, const QSize &size)
QT_BEGIN_NAMESPACE constexpr int QLAYOUTSIZE_MAX
Definition qlayoutitem.h:16
static const QMetaObjectPrivate * priv(const uint *data)
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLboolean r
[2]
GLint GLsizei width
GLenum GLuint GLintptr offset
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLdouble s
[6]
Definition qopenglext.h:235
#define sp
QObject::connect nullptr