1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the QtGui module of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qstackedwidget.h"
44 #ifndef QT_NO_STACKEDWIDGET
46 #include <qstackedlayout.h>
48 #include <private/qframe_p.h>
53 QStackedLayout does not support height for width (simply because it does not reimplement
54 heightForWidth() and hasHeightForWidth()). That is not possible to fix without breaking
55 binary compatibility. (QLayout is subject to multiple inheritance).
56 However, we can fix QStackedWidget by simply using a modified version of QStackedLayout
57 that reimplements the hfw-related functions:
59 class QStackedLayoutHFW : public QStackedLayout
62 QStackedLayoutHFW(QWidget *parent = 0) : QStackedLayout(parent) {}
63 bool hasHeightForWidth() const;
64 int heightForWidth(int width) const;
67 bool QStackedLayoutHFW::hasHeightForWidth() const
69 const int n = count();
71 for (int i = 0; i < n; ++i) {
72 if (QLayoutItem *item = itemAt(i)) {
73 if (item->hasHeightForWidth())
80 int QStackedLayoutHFW::heightForWidth(int width) const
82 const int n = count();
85 for (int i = 0; i < n; ++i) {
86 if (QLayoutItem *item = itemAt(i)) {
87 hfw = qMax(hfw, item->heightForWidth(width));
94 class QStackedWidgetPrivate : public QFramePrivate
96 Q_DECLARE_PUBLIC(QStackedWidget)
98 QStackedWidgetPrivate():layout(0){}
99 QStackedLayoutHFW *layout;
104 \class QStackedWidget
105 \brief The QStackedWidget class provides a stack of widgets where
106 only one widget is visible at a time.
109 \ingroup geomanagement
112 QStackedWidget can be used to create a user interface similar to
113 the one provided by QTabWidget. It is a convenience layout widget
114 built on top of the QStackedLayout class.
116 Like QStackedLayout, QStackedWidget can be constructed and
117 populated with a number of child widgets ("pages"):
119 \snippet doc/src/snippets/qstackedwidget/main.cpp 0
120 \snippet doc/src/snippets/qstackedwidget/main.cpp 2
121 \snippet doc/src/snippets/qstackedwidget/main.cpp 3
123 QStackedWidget provides no intrinsic means for the user to switch
124 page. This is typically done through a QComboBox or a QListWidget
125 that stores the titles of the QStackedWidget's pages. For
128 \snippet doc/src/snippets/qstackedwidget/main.cpp 1
130 When populating a stacked widget, the widgets are added to an
131 internal list. The indexOf() function returns the index of a
132 widget in that list. The widgets can either be added to the end of
133 the list using the addWidget() function, or inserted at a given
134 index using the insertWidget() function. The removeWidget()
135 function removes a widget from the stacked widget. The number of
136 widgets contained in the stacked widget, can
137 be obtained using the count() function.
139 The widget() function returns the widget at a given index
140 position. The index of the widget that is shown on screen is given
141 by currentIndex() and can be changed using setCurrentIndex(). In a
142 similar manner, the currently shown widget can be retrieved using
143 the currentWidget() function, and altered using the
144 setCurrentWidget() function.
146 Whenever the current widget in the stacked widget changes or a
147 widget is removed from the stacked widget, the currentChanged()
148 and widgetRemoved() signals are emitted respectively.
150 \sa QStackedLayout, QTabWidget, {Config Dialog Example}
154 \fn void QStackedWidget::currentChanged(int index)
156 This signal is emitted whenever the current widget changes.
158 The parameter holds the \a index of the new current widget, or -1
159 if there isn't a new one (for example, if there are no widgets in
162 \sa currentWidget(), setCurrentWidget()
166 \fn void QStackedWidget::widgetRemoved(int index)
168 This signal is emitted whenever a widget is removed. The widget's
169 \a index is passed as parameter.
175 Constructs a QStackedWidget with the given \a parent.
177 \sa addWidget(), insertWidget()
179 QStackedWidget::QStackedWidget(QWidget *parent)
180 : QFrame(*new QStackedWidgetPrivate, parent)
183 d->layout = new QStackedLayoutHFW(this);
184 connect(d->layout, SIGNAL(widgetRemoved(int)), this, SIGNAL(widgetRemoved(int)));
185 connect(d->layout, SIGNAL(currentChanged(int)), this, SIGNAL(currentChanged(int)));
189 Destroys this stacked widget, and frees any allocated resources.
191 QStackedWidget::~QStackedWidget()
196 Appends the given \a widget to the QStackedWidget and returns the
197 index position. Ownership of \a widget is passed on to the
200 If the QStackedWidget is empty before this function is called,
201 \a widget becomes the current widget.
203 \sa insertWidget(), removeWidget(), setCurrentWidget()
205 int QStackedWidget::addWidget(QWidget *widget)
207 return d_func()->layout->addWidget(widget);
211 Inserts the given \a widget at the given \a index in the
212 QStackedWidget. Ownership of \a widget is passed on to the
213 QStackedWidget. If \a index is out of range, the \a widget is
214 appended (in which case it is the actual index of the \a widget
217 If the QStackedWidget was empty before this function is called,
218 the given \a widget becomes the current widget.
220 Inserting a new widget at an index less than or equal to the current index
221 will increment the current index, but keep the current widget.
223 \sa addWidget(), removeWidget(), setCurrentWidget()
225 int QStackedWidget::insertWidget(int index, QWidget *widget)
227 return d_func()->layout->insertWidget(index, widget);
231 Removes \a widget from the QStackedWidget. i.e., \a widget is \e
232 not deleted but simply removed from the stacked layout, causing it
235 \b{Note:} Ownership of \a widget reverts to the application.
237 \sa addWidget(), insertWidget(), currentWidget()
239 void QStackedWidget::removeWidget(QWidget *widget)
241 d_func()->layout->removeWidget(widget);
245 \property QStackedWidget::currentIndex
246 \brief the index position of the widget that is visible
248 The current index is -1 if there is no current widget.
250 By default, this property contains a value of -1 because the stack
253 \sa currentWidget(), indexOf()
256 void QStackedWidget::setCurrentIndex(int index)
258 d_func()->layout->setCurrentIndex(index);
261 int QStackedWidget::currentIndex() const
263 return d_func()->layout->currentIndex();
267 Returns the current widget, or 0 if there are no child widgets.
269 \sa currentIndex(), setCurrentWidget()
271 QWidget *QStackedWidget::currentWidget() const
273 return d_func()->layout->currentWidget();
278 \fn void QStackedWidget::setCurrentWidget(QWidget *widget)
280 Sets the current widget to be the specified \a widget. The new
281 current widget must already be contained in this stacked widget.
283 \sa currentWidget(), setCurrentIndex()
285 void QStackedWidget::setCurrentWidget(QWidget *widget)
288 if (d->layout->indexOf(widget) == -1) {
289 qWarning("QStackedWidget::setCurrentWidget: widget %p not contained in stack", widget);
292 d->layout->setCurrentWidget(widget);
296 Returns the index of the given \a widget, or -1 if the given \a
297 widget is not a child of the QStackedWidget.
299 \sa currentIndex(), widget()
301 int QStackedWidget::indexOf(QWidget *widget) const
303 return d_func()->layout->indexOf(widget);
307 Returns the widget at the given \a index, or 0 if there is no such
310 \sa currentWidget(), indexOf()
312 QWidget *QStackedWidget::widget(int index) const
314 return d_func()->layout->widget(index);
318 \property QStackedWidget::count
319 \brief the number of widgets contained by this stacked widget
321 By default, this property contains a value of 0.
323 \sa currentIndex(), widget()
325 int QStackedWidget::count() const
327 return d_func()->layout->count();
331 bool QStackedWidget::event(QEvent *e)
333 return QFrame::event(e);
338 #endif // QT_NO_STACKEDWIDGET