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 "qstackedwidget.h"
5
6#include <qstackedlayout.h>
7#include <qevent.h>
8#include <private/qframe_p.h>
9
10QT_BEGIN_NAMESPACE
11
12class QStackedWidgetPrivate : public QFramePrivate
13{
14 Q_DECLARE_PUBLIC(QStackedWidget)
15public:
16 QStackedWidgetPrivate():layout(nullptr){}
17 QStackedLayout *layout;
18};
19
20/*!
21 \class QStackedWidget
22 \brief The QStackedWidget class provides a stack of widgets where
23 only one widget is visible at a time.
24
25 \ingroup organizers
26 \ingroup geomanagement
27 \inmodule QtWidgets
28
29 QStackedWidget can be used to create a user interface similar to
30 the one provided by QTabWidget. It is a convenience layout widget
31 built on top of the QStackedLayout class.
32
33 Like QStackedLayout, QStackedWidget can be constructed and
34 populated with a number of child widgets ("pages"):
35
36 \snippet qstackedwidget/main.cpp 0
37 \snippet qstackedwidget/main.cpp 2
38 \snippet qstackedwidget/main.cpp 3
39
40 QStackedWidget provides no intrinsic means for the user to switch
41 page. This is typically done through a QComboBox or a QListWidget
42 that stores the titles of the QStackedWidget's pages. For
43 example:
44
45 \snippet qstackedwidget/main.cpp 1
46
47 When populating a stacked widget, the widgets are added to an
48 internal list. The indexOf() function returns the index of a
49 widget in that list. The widgets can either be added to the end of
50 the list using the addWidget() function, or inserted at a given
51 index using the insertWidget() function. The removeWidget()
52 function removes a widget from the stacked widget. The number of
53 widgets contained in the stacked widget can
54 be obtained using the count() function.
55
56 The widget() function returns the widget at a given index
57 position. The index of the widget that is shown on screen is given
58 by currentIndex() and can be changed using setCurrentIndex(). In a
59 similar manner, the currently shown widget can be retrieved using
60 the currentWidget() function, and altered using the
61 setCurrentWidget() function.
62
63 Whenever the current widget in the stacked widget changes or a
64 widget is removed from the stacked widget, the currentChanged()
65 and widgetRemoved() signals are emitted respectively.
66
67 \sa QStackedLayout, QTabWidget
68*/
69
70/*!
71 \fn void QStackedWidget::currentChanged(int index)
72
73 This signal is emitted whenever the current widget changes.
74
75 The parameter holds the \a index of the new current widget, or -1
76 if there isn't a new one (for example, if there are no widgets in
77 the QStackedWidget).
78
79 \sa currentWidget(), setCurrentWidget()
80*/
81
82/*!
83 \fn void QStackedWidget::widgetRemoved(int index)
84
85 This signal is emitted whenever a widget is removed. The widget's
86 \a index is passed as parameter.
87
88 \sa removeWidget()
89*/
90
91/*!
92 Constructs a QStackedWidget with the given \a parent.
93
94 \sa addWidget(), insertWidget()
95*/
96QStackedWidget::QStackedWidget(QWidget *parent)
97 : QFrame(*new QStackedWidgetPrivate, parent)
98{
99 Q_D(QStackedWidget);
100 d->layout = new QStackedLayout(this);
101 connect(sender: d->layout, SIGNAL(widgetRemoved(int)), receiver: this, SIGNAL(widgetRemoved(int)));
102 connect(sender: d->layout, SIGNAL(currentChanged(int)), receiver: this, SIGNAL(currentChanged(int)));
103}
104
105/*!
106 Destroys this stacked widget, and frees any allocated resources.
107*/
108QStackedWidget::~QStackedWidget()
109{
110}
111
112/*!
113 Appends the given \a widget to the QStackedWidget and returns the
114 index position. Ownership of \a widget is passed on to the
115 QStackedWidget.
116
117 If the QStackedWidget is empty before this function is called,
118 \a widget becomes the current widget.
119
120 \sa insertWidget(), removeWidget(), setCurrentWidget()
121*/
122int QStackedWidget::addWidget(QWidget *widget)
123{
124 return d_func()->layout->addWidget(w: widget);
125}
126
127/*!
128 Inserts the given \a widget at the given \a index in the
129 QStackedWidget. Ownership of \a widget is passed on to the
130 QStackedWidget. If \a index is out of range, the \a widget is
131 appended (in which case it is the actual index of the \a widget
132 that is returned).
133
134 If the QStackedWidget was empty before this function is called,
135 the given \a widget becomes the current widget.
136
137 Inserting a new widget at an index less than or equal to the current index
138 will increment the current index, but keep the current widget.
139
140 \sa addWidget(), removeWidget(), setCurrentWidget()
141*/
142int QStackedWidget::insertWidget(int index, QWidget *widget)
143{
144 return d_func()->layout->insertWidget(index, w: widget);
145}
146
147/*!
148 Removes \a widget from the QStackedWidget. i.e., \a widget is \e
149 not deleted but simply removed from the stacked layout, causing it
150 to be hidden.
151
152 \note Parent object and parent widget of \a widget will remain the
153 QStackedWidget. If the application wants to reuse the removed
154 \a widget, then it is recommended to re-parent it.
155
156 \sa addWidget(), insertWidget(), currentWidget()
157*/
158void QStackedWidget::removeWidget(QWidget *widget)
159{
160 d_func()->layout->removeWidget(w: widget);
161}
162
163/*!
164 \property QStackedWidget::currentIndex
165 \brief the index position of the widget that is visible
166
167 The current index is -1 if there is no current widget.
168
169 By default, this property contains a value of -1 because the stack
170 is initially empty.
171
172 \sa currentWidget(), indexOf()
173*/
174
175void QStackedWidget::setCurrentIndex(int index)
176{
177 d_func()->layout->setCurrentIndex(index);
178}
179
180int QStackedWidget::currentIndex() const
181{
182 return d_func()->layout->currentIndex();
183}
184
185/*!
186 Returns the current widget, or \nullptr if there are no child widgets.
187
188 \sa currentIndex(), setCurrentWidget()
189*/
190QWidget *QStackedWidget::currentWidget() const
191{
192 return d_func()->layout->currentWidget();
193}
194
195
196/*!
197 \fn void QStackedWidget::setCurrentWidget(QWidget *widget)
198
199 Sets the current widget to be the specified \a widget. The new
200 current widget must already be contained in this stacked widget.
201
202 \sa currentWidget(), setCurrentIndex()
203 */
204void QStackedWidget::setCurrentWidget(QWidget *widget)
205{
206 Q_D(QStackedWidget);
207 if (Q_UNLIKELY(d->layout->indexOf(widget) == -1)) {
208 qWarning(msg: "QStackedWidget::setCurrentWidget: widget %p not contained in stack", widget);
209 return;
210 }
211 d->layout->setCurrentWidget(widget);
212}
213
214/*!
215 Returns the index of the given \a widget, or -1 if the given \a
216 widget is not a child of the QStackedWidget.
217
218 \sa currentIndex(), widget()
219*/
220int QStackedWidget::indexOf(const QWidget *widget) const
221{
222 return d_func()->layout->indexOf(widget);
223}
224
225/*!
226 Returns the widget at the given \a index, or \nullptr if there is
227 no such widget.
228
229 \sa currentWidget(), indexOf()
230*/
231QWidget *QStackedWidget::widget(int index) const
232{
233 return d_func()->layout->widget(index);
234}
235
236/*!
237 \property QStackedWidget::count
238 \brief the number of widgets contained by this stacked widget
239
240 By default, this property contains a value of 0.
241
242 \sa currentIndex(), widget()
243*/
244int QStackedWidget::count() const
245{
246 return d_func()->layout->count();
247}
248
249/*! \reimp */
250bool QStackedWidget::event(QEvent *e)
251{
252 return QFrame::event(e);
253}
254
255QT_END_NAMESPACE
256
257#include "moc_qstackedwidget.cpp"
258

source code of qtbase/src/widgets/widgets/qstackedwidget.cpp