📄 qlayout.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qlayout.h"#include "qapplication.h"#include "qlayoutengine_p.h"#include "qmenubar.h"#include "qtoolbar.h"#include "qevent.h"#include "qstyle.h"#include "qvariant.h"#include "qwidget_p.h"#include "qlayout_p.h"static int menuBarHeightForWidth(QWidget *menubar, int w){ if (menubar && !menubar->isHidden() && !menubar->isWindow()) { int result = menubar->heightForWidth(qMax(w, menubar->minimumWidth())); if (result != -1) return result; result = menubar->sizeHint().height(); if (result != -1) return result; } return 0;}/*! \class QLayout \brief The QLayout class is the base class of geometry managers. \ingroup appearance \ingroup geomanagement This is an abstract base class inherited by the concrete classes QBoxLayout, QGridLayout, and QStackedLayout. For users of QLayout subclasses or of QMainWindow there is seldom any need to use the basic functions provided by QLayout, such as setSizeConstraint() or setMenuBar(). See \l{Layout Classes} for more information. To make your own layout manager, implement the functions addItem(), sizeHint(), setGeometry(), itemAt() and takeAt(). You should also implement minimumSize() to ensure your layout isn't resized to zero size if there is too little space. To support children whose heights depend on their widths, implement hasHeightForWidth() and heightForWidth(). See the \l{layouts/borderlayout}{Border Layout} and \l{layouts/flowlayout}{Flow Layout} examples for more information about implementing custom layout managers. Geometry management stops when the layout manager is deleted. \sa QLayoutItem, {Layout Classes}, {Basic Layouts Example}, {Border Layout Example}, {Flow Layout Example}*//*! Constructs a new top-level QLayout, with parent \a parent. \a parent may not be 0. There can be only one top-level layout for a widget. It is returned by QWidget::layout().*/QLayout::QLayout(QWidget *parent) : QObject(*new QLayoutPrivate, parent){ if (!parent) return; parent->setLayout(this);}/*! Constructs a new child QLayout. This layout has to be inserted into another layout before geometry management will work.*/QLayout::QLayout() : QObject(*new QLayoutPrivate, 0){}/*! \internal */QLayout::QLayout(QLayoutPrivate &dd, QLayout *lay, QWidget *w) : QObject(dd, lay ? static_cast<QObject*>(lay) : static_cast<QObject*>(w)){ Q_D(QLayout); if (lay) { lay->addItem(this); } else if (w) { if (w->layout()) { qWarning("QLayout: Attempting to add QLayout \"%s\" to %s \"%s\", which" " already has a layout", qPrintable(QObject::objectName()), w->metaObject()->className(), w->objectName().toLocal8Bit().data()); setParent(0); } else { d->topLevel = true; w->d_func()->layout = this; invalidate(); } }}QLayoutPrivate::QLayoutPrivate() : QObjectPrivate(), insideSpacing(-1), userLeftMargin(-1), userTopMargin(-1), userRightMargin(-1), userBottomMargin(-1), topLevel(false), enabled(true), activated(true), autoNewChild(false), constraint(QLayout::SetDefaultConstraint), menubar(0){}void QLayoutPrivate::getMargin(int *result, int userMargin, QStyle::PixelMetric pm) const{ if (!result) return; Q_Q(const QLayout); if (userMargin >= 0) { *result = userMargin; } else if (!topLevel) { *result = 0; } else if (QWidget *pw = q->parentWidget()) { *result = pw->style()->pixelMetric(pm, 0, pw); } else { *result = 0; }}#ifdef QT3_SUPPORT/*! Constructs a new top-level QLayout called \a name, with parent widget \a parent. \a parent may not be 0. The \a margin is the number of pixels between the edge of the widget and the managed children. The \a spacing sets the value of spacing(), which gives the spacing between the managed widgets. If \a spacing is -1 (the default), spacing is set to the value of \a margin. There can be only one top-level layout for a widget. It is returned by QWidget::layout() \sa QWidget::setLayout()*/QLayout::QLayout(QWidget *parent, int margin, int spacing, const char *name) : QObject(*new QLayoutPrivate,parent){ Q_D(QLayout); setObjectName(QString::fromAscii(name)); setMargin(margin); if (spacing < 0) d->insideSpacing = margin; else d->insideSpacing = spacing; if (parent) { if (parent->layout()) { qWarning("QLayout \"%s\" added to %s \"%s\", which already has a layout", QObject::objectName().toLocal8Bit().data(), parent->metaObject()->className(), parent->objectName().toLocal8Bit().data()); parent->layout()->setParent(0); } else { d->topLevel = true; parent->d_func()->layout = this; invalidate(); } }}/*! Constructs a new child QLayout called \a name, and places it inside \a parentLayout by using the default placement defined by addItem(). If \a spacing is -1, this QLayout inherits \a parentLayout's spacing(), otherwise the value of \a spacing is used.*/QLayout::QLayout(QLayout *parentLayout, int spacing, const char *name) : QObject(*new QLayoutPrivate,parentLayout){ Q_D(QLayout); setObjectName(QString::fromAscii(name)); d->insideSpacing = spacing; parentLayout->addItem(this);}/*! Constructs a new child QLayout called \a name. If \a spacing is -1, this QLayout inherits its parent's spacing(); otherwise the value of \a spacing is used. This layout has to be inserted into another layout before geometry management will work.*/QLayout::QLayout(int spacing, const char *name) : QObject(*new QLayoutPrivate, 0){ Q_D(QLayout); setObjectName(QString::fromAscii(name)); d->insideSpacing = spacing;}/*! Automatically adding widgets is deprecated. Use addWidget() or addLayout() instead.*/void QLayout::setAutoAdd(bool a) { Q_D(QLayout); d->autoNewChild = a; }/*! Automatically adding widgets is deprecated. Use addWidget() or addLayout() instead.*/bool QLayout::autoAdd() const { Q_D(const QLayout); return d->autoNewChild; }#endif/*! \fn void QLayout::addItem(QLayoutItem *item) Implemented in subclasses to add an \a item. How it is added is specific to each subclass. This function is not usually called in application code. To add a widget to a layout, use the addWidget() function; to add a child layout, use the addLayout() function provided by the relevant QLayout subclass. \bold{Note:} The ownership of \a item is transferred to the layout, and it's the layout's responsibility to delete it. \sa addWidget(), QBoxLayout::addLayout(), QGridLayout::addLayout()*//*! Adds widget \a w to this layout in a manner specific to the layout. This function uses addItem().*/void QLayout::addWidget(QWidget *w){ addChildWidget(w); addItem(new QWidgetItem(w));}/*! Sets the alignment for widget \a w to \a alignment and returns true if \a w is found in this layout (not including child layouts); otherwise returns false.*/bool QLayout::setAlignment(QWidget *w, Qt::Alignment alignment){ int i = 0; QLayoutItem *item = itemAt(i); while (item) { if (item->widget() == w) { item->setAlignment(alignment); invalidate(); return true; } ++i; item = itemAt(i); } return false;}/*! \overload Sets the alignment for the layout \a l to \a alignment and returns true if \a l is found in this layout (not including child layouts); otherwise returns false.*/bool QLayout::setAlignment(QLayout *l, Qt::Alignment alignment){ int i = 0; QLayoutItem *item = itemAt(i); while (item) { if (item->layout() == l) { item->setAlignment(alignment); invalidate(); return true; } ++i; item = itemAt(i); } return false;}/*! \fn void QLayout::setAlignment(Qt::Alignment alignment) Sets the alignment of this item to \a alignment. \sa QLayoutItem::setAlignment()*//*! \fn bool QLayout::isTopLevel() const Returns true if this layout is a top-level layout, i.e. not a child of another layout; otherwise returns false.*//*! \property QLayout::margin \brief the width of the outside border of the layout \obsolete Use setContentsMargins() and getContentsMargins() instead. \sa contentsRect(), spacing*//*! \obsolete*/int QLayout::margin() const{ int left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); if (left == top && top == right && right == bottom) { return left; } else { return -1; }}/*! \property QLayout::spacing \brief the spacing between widgets inside the layout If no value is explicitly set, the layout's spacing is inherited from the parent layout, or from the style settings for the parent widget. For QGridLayout, it is possible to set different horizontal and vertical spacings using \l{QGridLayout::}{setHorizontalSpacing()} and \l{QGridLayout::}{setVerticalSpacing()}. In that case, spacing() returns -1. \sa contentsRect(), getContentsMargins(), QStyle::layoutSpacing(), QStyle::pixelMetric()*/int QLayout::spacing() const{ if (const QBoxLayout* boxlayout = qobject_cast<const QBoxLayout*>(this)) { return boxlayout->spacing(); } else if (const QGridLayout* gridlayout = qobject_cast<const QGridLayout*>(this)) { return gridlayout->spacing(); } else { Q_D(const QLayout); if (d->insideSpacing >=0) { return d->insideSpacing; } else { // arbitrarily prefer horizontal spacing to vertical spacing return qSmartSpacing(this, QStyle::PM_LayoutHorizontalSpacing); } }}/*! \obsolete*/void QLayout::setMargin(int margin){ setContentsMargins(margin, margin, margin, margin);}void QLayout::setSpacing(int spacing){ if (QBoxLayout* boxlayout = qobject_cast<QBoxLayout*>(this)) { boxlayout->setSpacing(spacing); } else if (QGridLayout* gridlayout = qobject_cast<QGridLayout*>(this)) { gridlayout->setSpacing(spacing); } else { Q_D(QLayout); d->insideSpacing = spacing; invalidate(); }}/*! \since 4.3 Sets the \a left, \a top, \a right, and \a bottom margins to use around the layout. By default, QLayout uses the values provided by the style. On most platforms, the margin is 11 pixels in all directions. \sa getContentsMargins(), QStyle::pixelMetric(), {QStyle::}{PM_LayoutLeftMargin}, {QStyle::}{PM_LayoutTopMargin}, {QStyle::}{PM_LayoutRightMargin}, {QStyle::}{PM_LayoutBottomMargin}*/void QLayout::setContentsMargins(int left, int top, int right, int bottom){ Q_D(QLayout); d->userLeftMargin = left; d->userTopMargin = top; d->userRightMargin = right; d->userBottomMargin = bottom; invalidate();}/*! \since 4.3 Extracts the left, top, right, and bottom margins used around the layout, and assigns them to *\a left, *\a top, *\a right, and *\a bottom (unless they are null pointers). By default, QLayout uses the values provided by the style. On most platforms, the margin is 11 pixels in all directions. \sa setContentsMargins(), QStyle::pixelMetric(), {QStyle::}{PM_LayoutLeftMargin}, {QStyle::}{PM_LayoutTopMargin}, {QStyle::}{PM_LayoutRightMargin}, {QStyle::}{PM_LayoutBottomMargin}*/void QLayout::getContentsMargins(int *left, int *top, int *right, int *bottom) const{ Q_D(const QLayout); d->getMargin(left, d->userLeftMargin, QStyle::PM_LayoutLeftMargin); d->getMargin(top, d->userTopMargin, QStyle::PM_LayoutTopMargin); d->getMargin(right, d->userRightMargin, QStyle::PM_LayoutRightMargin); d->getMargin(bottom, d->userBottomMargin, QStyle::PM_LayoutBottomMargin);}/*! \since 4.3 Returns the layout's geometry() rectangle, but taking into account the contents margins. \sa setContentsMargins(), getContentsMargins()*/QRect QLayout::contentsRect() const{ Q_D(const QLayout); int left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); return d->rect.adjusted(+left, +top, -right, -bottom);}#ifdef QT3_SUPPORTbool QLayout::isTopLevel() const{ Q_D(const QLayout); return d->topLevel;}#endif/*! Returns the parent widget of this layout, or 0 if this layout is not installed on any widget. If the layout is a sub-layout, this function returns the parent widget of the parent layout. \sa parent()*/QWidget *QLayout::parentWidget() const{ Q_D(const QLayout); if (!d->topLevel) { if (parent()) { QLayout *parentLayout = ::qobject_cast<QLayout*>(parent()); Q_ASSERT(parentLayout); return parentLayout->parentWidget(); } else { return 0; } } else { Q_ASSERT(parent() && parent()->isWidgetType()); return static_cast<QWidget *>(parent()); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -