1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtWidgets module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qstackedwidget.h"
41 
42 #include <qstackedlayout.h>
43 #include <qevent.h>
44 #include <private/qframe_p.h>
45 
46 QT_BEGIN_NAMESPACE
47 
48 class QStackedWidgetPrivate : public QFramePrivate
49 {
50     Q_DECLARE_PUBLIC(QStackedWidget)
51 public:
QStackedWidgetPrivate()52     QStackedWidgetPrivate():layout(nullptr){}
53     QStackedLayout *layout;
54     bool blockChildAdd;
55 };
56 
57 /*!
58     \class QStackedWidget
59     \brief The QStackedWidget class provides a stack of widgets where
60     only one widget is visible at a time.
61 
62     \ingroup organizers
63     \ingroup geomanagement
64     \inmodule QtWidgets
65 
66     QStackedWidget can be used to create a user interface similar to
67     the one provided by QTabWidget. It is a convenience layout widget
68     built on top of the QStackedLayout class.
69 
70     Like QStackedLayout, QStackedWidget can be constructed and
71     populated with a number of child widgets ("pages"):
72 
73     \snippet qstackedwidget/main.cpp 0
74     \snippet qstackedwidget/main.cpp 2
75     \snippet qstackedwidget/main.cpp 3
76 
77     QStackedWidget provides no intrinsic means for the user to switch
78     page. This is typically done through a QComboBox or a QListWidget
79     that stores the titles of the QStackedWidget's pages. For
80     example:
81 
82     \snippet qstackedwidget/main.cpp 1
83 
84     When populating a stacked widget, the widgets are added to an
85     internal list. The indexOf() function returns the index of a
86     widget in that list. The widgets can either be added to the end of
87     the list using the addWidget() function, or inserted at a given
88     index using the insertWidget() function. The removeWidget()
89     function removes a widget from the stacked widget. The number of
90     widgets contained in the stacked widget can
91     be obtained using the count() function.
92 
93     The widget() function returns the widget at a given index
94     position. The index of the widget that is shown on screen is given
95     by currentIndex() and can be changed using setCurrentIndex(). In a
96     similar manner, the currently shown widget can be retrieved using
97     the currentWidget() function, and altered using the
98     setCurrentWidget() function.
99 
100     Whenever the current widget in the stacked widget changes or a
101     widget is removed from the stacked widget, the currentChanged()
102     and widgetRemoved() signals are emitted respectively.
103 
104     \sa QStackedLayout, QTabWidget
105 */
106 
107 /*!
108     \fn void QStackedWidget::currentChanged(int index)
109 
110     This signal is emitted whenever the current widget changes.
111 
112     The parameter holds the \a index of the new current widget, or -1
113     if there isn't a new one (for example, if there are no widgets in
114     the QStackedWidget).
115 
116     \sa currentWidget(), setCurrentWidget()
117 */
118 
119 /*!
120     \fn void QStackedWidget::widgetRemoved(int index)
121 
122     This signal is emitted whenever a widget is removed. The widget's
123     \a index is passed as parameter.
124 
125     \sa removeWidget()
126 */
127 
128 /*!
129     Constructs a QStackedWidget with the given \a parent.
130 
131     \sa addWidget(), insertWidget()
132 */
QStackedWidget(QWidget * parent)133 QStackedWidget::QStackedWidget(QWidget *parent)
134     : QFrame(*new QStackedWidgetPrivate, parent)
135 {
136     Q_D(QStackedWidget);
137     d->layout = new QStackedLayout(this);
138     connect(d->layout, SIGNAL(widgetRemoved(int)), this, SIGNAL(widgetRemoved(int)));
139     connect(d->layout, SIGNAL(currentChanged(int)), this, SIGNAL(currentChanged(int)));
140 }
141 
142 /*!
143     Destroys this stacked widget, and frees any allocated resources.
144 */
~QStackedWidget()145 QStackedWidget::~QStackedWidget()
146 {
147 }
148 
149 /*!
150     Appends the given \a widget to the QStackedWidget and returns the
151     index position. Ownership of \a widget is passed on to the
152     QStackedWidget.
153 
154     If the QStackedWidget is empty before this function is called,
155     \a widget becomes the current widget.
156 
157     \sa insertWidget(), removeWidget(), setCurrentWidget()
158 */
addWidget(QWidget * widget)159 int QStackedWidget::addWidget(QWidget *widget)
160 {
161     return d_func()->layout->addWidget(widget);
162 }
163 
164 /*!
165     Inserts the given \a widget at the given \a index in the
166     QStackedWidget. Ownership of \a widget is passed on to the
167     QStackedWidget. If \a index is out of range, the \a widget is
168     appended (in which case it is the actual index of the \a widget
169     that is returned).
170 
171     If the QStackedWidget was empty before this function is called,
172     the given \a widget becomes the current widget.
173 
174     Inserting a new widget at an index less than or equal to the current index
175     will increment the current index, but keep the current widget.
176 
177     \sa addWidget(), removeWidget(), setCurrentWidget()
178 */
insertWidget(int index,QWidget * widget)179 int QStackedWidget::insertWidget(int index, QWidget *widget)
180 {
181     return d_func()->layout->insertWidget(index, widget);
182 }
183 
184 /*!
185     Removes \a widget from the QStackedWidget. i.e., \a widget is \e
186     not deleted but simply removed from the stacked layout, causing it
187     to be hidden.
188 
189     \note Parent object and parent widget of \a widget will remain the
190     QStackedWidget. If the application wants to reuse the removed
191     \a widget, then it is recommended to re-parent it.
192 
193     \sa addWidget(), insertWidget(), currentWidget()
194 */
removeWidget(QWidget * widget)195 void QStackedWidget::removeWidget(QWidget *widget)
196 {
197     d_func()->layout->removeWidget(widget);
198 }
199 
200 /*!
201     \property QStackedWidget::currentIndex
202     \brief the index position of the widget that is visible
203 
204     The current index is -1 if there is no current widget.
205 
206     By default, this property contains a value of -1 because the stack
207     is initially empty.
208 
209     \sa currentWidget(), indexOf()
210 */
211 
setCurrentIndex(int index)212 void QStackedWidget::setCurrentIndex(int index)
213 {
214     d_func()->layout->setCurrentIndex(index);
215 }
216 
currentIndex() const217 int QStackedWidget::currentIndex() const
218 {
219     return d_func()->layout->currentIndex();
220 }
221 
222 /*!
223     Returns the current widget, or \nullptr if there are no child widgets.
224 
225     \sa currentIndex(), setCurrentWidget()
226 */
currentWidget() const227 QWidget *QStackedWidget::currentWidget() const
228 {
229     return d_func()->layout->currentWidget();
230 }
231 
232 
233 /*!
234     \fn void QStackedWidget::setCurrentWidget(QWidget *widget)
235 
236     Sets the current widget to be the specified \a widget. The new
237     current widget must already be contained in this stacked widget.
238 
239     \sa currentWidget(), setCurrentIndex()
240  */
setCurrentWidget(QWidget * widget)241 void QStackedWidget::setCurrentWidget(QWidget *widget)
242 {
243     Q_D(QStackedWidget);
244     if (Q_UNLIKELY(d->layout->indexOf(widget) == -1)) {
245         qWarning("QStackedWidget::setCurrentWidget: widget %p not contained in stack", widget);
246         return;
247     }
248     d->layout->setCurrentWidget(widget);
249 }
250 
251 /*!
252     Returns the index of the given \a widget, or -1 if the given \a
253     widget is not a child of the QStackedWidget.
254 
255     \sa currentIndex(), widget()
256 */
indexOf(QWidget * widget) const257 int QStackedWidget::indexOf(QWidget *widget) const
258 {
259     return d_func()->layout->indexOf(widget);
260 }
261 
262 /*!
263     Returns the widget at the given \a index, or \nullptr if there is
264     no such widget.
265 
266     \sa currentWidget(), indexOf()
267 */
widget(int index) const268 QWidget *QStackedWidget::widget(int index) const
269 {
270     return d_func()->layout->widget(index);
271 }
272 
273 /*!
274     \property QStackedWidget::count
275     \brief the number of widgets contained by this stacked widget
276 
277     By default, this property contains a value of 0.
278 
279     \sa currentIndex(), widget()
280 */
count() const281 int QStackedWidget::count() const
282 {
283     return d_func()->layout->count();
284 }
285 
286 /*! \reimp */
event(QEvent * e)287 bool QStackedWidget::event(QEvent *e)
288 {
289     return QFrame::event(e);
290 }
291 
292 QT_END_NAMESPACE
293 
294 #include "moc_qstackedwidget.cpp"
295