📄 qlayout.cpp
字号:
}/*! \reimp*/bool QLayout::isEmpty() const{ int i = 0; QLayoutItem *item = itemAt(i); while (item) { if (!item->isEmpty()) return false; ++i; item = itemAt(i); } return true;}/*! \reimp*/void QLayout::setGeometry(const QRect &r){ Q_D(QLayout); d->rect = r;}/*! \reimp*/QRect QLayout::geometry() const{ Q_D(const QLayout); return d->rect;}/*! \reimp*/void QLayout::invalidate(){ Q_D(QLayout); d->rect = QRect(); update();}static bool removeWidgetRecursively(QLayoutItem *li, QWidget *w){ QLayout *lay = li->layout(); if (!lay) return false; int i = 0; QLayoutItem *child; while ((child = lay->itemAt(i))) { if (child->widget() == w) { delete lay->takeAt(i); lay->invalidate(); return true; } else if (removeWidgetRecursively(child, w)) { return true; } else { ++i; } } return false;}void QLayoutPrivate::doResize(const QSize &r){ Q_Q(QLayout); int mbh = menuBarHeightForWidth(menubar, r.width()); QWidget *mw = q->parentWidget(); QRect rect = mw->testAttribute(Qt::WA_LayoutOnEntireRect) ? mw->rect() : mw->contentsRect(); rect.setTop(rect.top() + mbh); q->setGeometry(rect);#ifndef QT_NO_MENUBAR if (menubar) menubar->setGeometry(0,0,r.width(), mbh);#endif}/*! \internal Performs child widget layout when the parent widget is resized. Also handles removal of widgets. \a e is the event*/void QLayout::widgetEvent(QEvent *e){ Q_D(QLayout); if (!d->enabled) return; switch (e->type()) { case QEvent::Resize: if (d->activated) { QResizeEvent *r = (QResizeEvent *)e; d->doResize(r->size()); } else { activate(); } break; case QEvent::ChildRemoved: { QChildEvent *c = (QChildEvent *)e; if (c->child()->isWidgetType()) { QWidget *w = (QWidget *)c->child();#ifndef QT_NO_MENUBAR if (w == d->menubar) d->menubar = 0;#endif removeWidgetRecursively(this, w); } } break;#ifdef QT3_SUPPORT case QEvent::ChildInserted: if (d->topLevel && d->autoNewChild) { QChildEvent *c = (QChildEvent *)e; if (c->child()->isWidgetType()) { QWidget *w = (QWidget *)c->child(); if (!w->isWindow()) {#if !defined(QT_NO_MENUBAR) && !defined(QT_NO_TOOLBAR) if (qobject_cast<QMenuBar*>(w) && !::qobject_cast<QToolBar*>(w->parentWidget())) { d->menubar = (QMenuBar *)w; invalidate(); } else#endif addItem(new QWidgetItem(w)); } } } break; case QEvent::LayoutHint: d->activated = false; // fall through#endif case QEvent::LayoutRequest: activate(); break; default: break; }}/*! \reimp*/void QLayout::childEvent(QChildEvent *e){ Q_D(QLayout); if (!d->enabled) return; if (e->type() == QEvent::ChildRemoved) { QChildEvent *c = (QChildEvent*)e; int i = 0; QLayoutItem *item; while ((item = itemAt(i))) { if (item == static_cast<QLayout*>(c->child())) { takeAt(i); invalidate(); break; } else { ++i; } } }}/*! \internal Also takes contentsMargins and menu bar into account.*/int QLayout::totalHeightForWidth(int w) const{ Q_D(const QLayout); int side=0, top=0; if (d->topLevel) { QWidget *parent = parentWidget(); parent->ensurePolished(); QWidgetPrivate *wd = parent->d_func(); side += wd->leftmargin + wd->rightmargin; top += wd->topmargin + wd->bottommargin; } int h = heightForWidth(w - side) + top;#ifndef QT_NO_MENUBAR h += menuBarHeightForWidth(d->menubar, w);#endif return h;}/*! \internal Also takes contentsMargins and menu bar into account.*/QSize QLayout::totalMinimumSize() const{ Q_D(const QLayout); int side=0, top=0; if (d->topLevel) { QWidget *pw = parentWidget(); pw->ensurePolished(); QWidgetPrivate *wd = pw->d_func(); side += wd->leftmargin + wd->rightmargin; top += wd->topmargin + wd->bottommargin; } QSize s = minimumSize();#ifndef QT_NO_MENUBAR top += menuBarHeightForWidth(d->menubar, s.width() + side);#endif return s + QSize(side, top);}/*! \internal Also takes contentsMargins and menu bar into account.*/QSize QLayout::totalSizeHint() const{ Q_D(const QLayout); int side=0, top=0; if (d->topLevel) { QWidget *pw = parentWidget(); pw->ensurePolished(); QWidgetPrivate *wd = pw->d_func(); side += wd->leftmargin + wd->rightmargin; top += wd->topmargin + wd->bottommargin; } QSize s = sizeHint(); if (hasHeightForWidth()) s.setHeight(heightForWidth(s.width() + side));#ifndef QT_NO_MENUBAR top += menuBarHeightForWidth(d->menubar, s.width());#endif return s + QSize(side, top);}/*! \internal Also takes contentsMargins and menu bar into account.*/QSize QLayout::totalMaximumSize() const{ Q_D(const QLayout); int side=0, top=0; if (d->topLevel) { QWidget *pw = parentWidget(); pw->ensurePolished(); QWidgetPrivate *wd = pw->d_func(); side += wd->leftmargin + wd->rightmargin; top += wd->topmargin + wd->bottommargin; } QSize s = maximumSize();#ifndef QT_NO_MENUBAR top += menuBarHeightForWidth(d->menubar, s.width());#endif if (d->topLevel) s = QSize(qMin(s.width() + side, QLAYOUTSIZE_MAX), qMin(s.height() + top, QLAYOUTSIZE_MAX)); return s;}/*! \internal Destroys the layout, deleting all child layouts. Geometry management stops when a top-level layout is deleted. The layout classes will probably be fatally confused if you delete a sublayout.*/QLayout::~QLayout(){ Q_D(QLayout); /* This function may be called during the QObject destructor, when the parent no longer is a QWidget. */ if (d->topLevel && parent() && parent()->isWidgetType() && ((QWidget*)parent())->layout() == this) ((QWidget*)parent())->d_func()->layout = 0;}#ifdef QT3_SUPPORT/*! Removes and deletes all items in this layout.*/void QLayout::deleteAllItems(){ QLayoutItem *l; while ((l = takeAt(0))) delete l;}#endif/*! This function is called from \c addLayout() or \c insertLayout() functions in subclasses to add layout \a l as a sub-layout. The only scenario in which you need to call it directly is if you implement a custom layout that supports nested layouts. \sa QBoxLayout::addLayout(), QBoxLayout::insertLayout(), QGridLayout::addLayout()*/void QLayout::addChildLayout(QLayout *l){ if (l->parent()) { qWarning("QLayout::addChildLayout: layout \"%s\" already has a parent", l->objectName().toLocal8Bit().data()); return; } l->setParent(this); if (QWidget *mw = parentWidget()) { l->d_func()->reparentChildWidgets(mw); }}#ifdef QT_DEBUGstatic bool layoutDebug(){ static int checked_env = -1; if(checked_env == -1) checked_env = !!qgetenv("QT_LAYOUT_DEBUG").toInt(); return checked_env;}#endifvoid QLayoutPrivate::reparentChildWidgets(QWidget *mw){ Q_Q(QLayout); int n = q->count();#ifndef QT_NO_MENUBAR if (menubar && menubar->parentWidget() != mw) { menubar->setParent(mw); }#endif bool mwVisible = mw && mw->isVisible(); for (int i = 0; i < n; ++i) { QLayoutItem *item = q->itemAt(i); if (QWidget *w = item->widget()) { QWidget *pw = w->parentWidget();#ifdef QT_DEBUG if (pw && pw != mw && layoutDebug()) { qWarning("QLayout::addChildLayout: widget %s \"%s\" in wrong parent; moved to correct parent", w->metaObject()->className(), w->objectName().toLocal8Bit().data()); }#endif bool needShow = mwVisible && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide)); if (pw != mw) w->setParent(mw); if (needShow) QMetaObject::invokeMethod(w, "_q_showIfNotHidden", Qt::QueuedConnection); //show later } else if (QLayout *l = item->layout()) { l->d_func()->reparentChildWidgets(mw); } }}/*! This function is called from \c addWidget() functions in subclasses to add \a w as a child widget. If \a w is already in a layout, this function will give a warning and remove \a w from the layout. This function must therefore be called before adding \a w to the layout's data structure.*/void QLayout::addChildWidget(QWidget *w){ QWidget *mw = parentWidget(); QWidget *pw = w->parentWidget(); //Qt::WA_LaidOut is never reset. It only means that the widget at some point has //been in a layout. if (pw && w->testAttribute(Qt::WA_LaidOut)) { QLayout *l = pw->layout(); if (l && removeWidgetRecursively(l, w)) {#ifdef QT_DEBUG if (layoutDebug()) qWarning("QLayout::addChildWidget: %s \"%s\" is already in a layout; moved to new layout", w->metaObject()->className(), w->objectName().toLocal8Bit().data());#endif } } if (pw && mw && pw != mw) {#ifdef QT_DEBUG if (layoutDebug()) qWarning("QLayout::addChildWidget: %s \"%s\" in wrong parent; moved to correct parent", w->metaObject()->className(), w->objectName().toLocal8Bit().data());#endif pw = 0; } bool needShow = mw && mw->isVisible() && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide)); if (!pw && mw) w->setParent(mw); w->setAttribute(Qt::WA_LaidOut); if (needShow) QMetaObject::invokeMethod(w, "_q_showIfNotHidden", Qt::QueuedConnection); //show later}#ifdef QT3_SUPPORT/*! \compat Sets this layout's parent widget to a fixed size with width \a w and height \a h, stopping the user from resizing it, and also prevents the layout from resizing it, even if the layout's size hint should change. Does nothing if this is not a top-level layout (i.e., if parent()->isWidgetType()). As a special case, if both \a w and \a h are 0, then the layout's current sizeHint() is used. Use \c setResizeMode(Fixed) to stop the widget from being resized by the user, while still allowing the layout to resize it when the sizeHint() changes. Use \c setResizeMode(FreeResize) to allow the user to resize the widget, while preventing the layout from resizing it.*/void QLayout::freeze(int w, int h){ Q_D(QLayout); if (!d->topLevel) return; if (w <= 0 || h <= 0) { QSize s = totalSizeHint(); w = s.width(); h = s.height(); } setSizeConstraint(SetNoConstraint); // layout will not change min/max size QWidget *parent = parentWidget(); if (parent) parent->setFixedSize(w, h);}#endif/*! Tells the geometry manager to place the menu bar \a widget at the top of parentWidget(), outside QWidget::contentsMargins(). All child widgets are placed below the bottom edge of the menu bar.*/void QLayout::setMenuBar(QWidget *widget){ Q_D(QLayout); if (widget) addChildWidget(widget); d->menubar = widget;}/*! Returns the menu bar set for this layout, or 0 if no menu bar is set.*/QWidget *QLayout::menuBar() const{ Q_D(const QLayout); return d->menubar;}/*! Returns the minimum size of this layout. This is the smallest size that the layout can have while still respecting the specifications. The returned value doesn't include the space required by QWidget::setContentsMargins() or menuBar(). The default implementation allows unlimited resizing.*/QSize QLayout::minimumSize() const{ return QSize(0, 0);}/*! Returns the maximum size of this layout. This is the largest size that the layout can have while still respecting the specifications. The returned value doesn't include the space required by QWidget::setContentsMargins() or menuBar(). The default implementation allows unlimited resizing.*/QSize QLayout::maximumSize() const{ return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);}/*! Returns whether this layout can make use of more space than sizeHint(). A value of Qt::Vertical or Qt::Horizontal means that it wants to grow in only one dimension, whereas Qt::Vertical | Qt::Horizontal means that it wants to grow in both dimensions. The default implementation returns Qt::Horizontal | Qt::Vertical. Subclasses reimplement it to return a meaningful value based on their child widgets's \l{QSizePolicy}{size policies}.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -