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 \fn void QStackedWidget::widgetAdded(int index)
93
94 \since 6.9
95
96 This signal is emitted whenever a widget is added or inserted.
97 The widget's \a index is passed as parameter.
98
99 \sa addWidget(), insertWidget()
100*/
101
102
103/*!
104 Constructs a QStackedWidget with the given \a parent.
105
106 \sa addWidget(), insertWidget()
107*/
108QStackedWidget::QStackedWidget(QWidget *parent)
109 : QFrame(*new QStackedWidgetPrivate, parent)
110{
111 Q_D(QStackedWidget);
112 d->layout = new QStackedLayout(this);
113 connect(sender: d->layout, signal: &QStackedLayout::widgetRemoved,
114 context: this, slot: &QStackedWidget::widgetRemoved);
115 connect(sender: d->layout, signal: &QStackedLayout::currentChanged,
116 context: this, slot: &QStackedWidget::currentChanged);
117 connect(sender: d->layout, signal: &QStackedLayout::widgetAdded,
118 context: this, slot: &QStackedWidget::widgetAdded);
119}
120
121/*!
122 Destroys this stacked widget, and frees any allocated resources.
123*/
124QStackedWidget::~QStackedWidget()
125{
126}
127
128/*!
129 Appends the given \a widget to the QStackedWidget and returns the
130 index position. Ownership of \a widget is passed on to the
131 QStackedWidget.
132
133 If the QStackedWidget is empty before this function is called,
134 \a widget becomes the current widget.
135
136 \sa insertWidget(), removeWidget(), setCurrentWidget()
137*/
138int QStackedWidget::addWidget(QWidget *widget)
139{
140 return d_func()->layout->addWidget(w: widget);
141}
142
143/*!
144 Inserts the given \a widget at the given \a index in the
145 QStackedWidget. Ownership of \a widget is passed on to the
146 QStackedWidget. If \a index is out of range, the \a widget is
147 appended (in which case it is the actual index of the \a widget
148 that is returned).
149
150 If the QStackedWidget was empty before this function is called,
151 the given \a widget becomes the current widget.
152
153 Inserting a new widget at an index less than or equal to the current index
154 will increment the current index, but keep the current widget.
155
156 \sa addWidget(), removeWidget(), setCurrentWidget()
157*/
158int QStackedWidget::insertWidget(int index, QWidget *widget)
159{
160 return d_func()->layout->insertWidget(index, w: widget);
161}
162
163/*!
164 Removes \a widget from the QStackedWidget. i.e., \a widget is \e
165 not deleted but simply removed from the stacked layout, causing it
166 to be hidden.
167
168 \note Parent object and parent widget of \a widget will remain the
169 QStackedWidget. If the application wants to reuse the removed
170 \a widget, then it is recommended to re-parent it.
171
172 \sa addWidget(), insertWidget(), currentWidget()
173*/
174void QStackedWidget::removeWidget(QWidget *widget)
175{
176 d_func()->layout->removeWidget(w: widget);
177}
178
179/*!
180 \property QStackedWidget::currentIndex
181 \brief the index position of the widget that is visible
182
183 The current index is -1 if there is no current widget.
184
185 By default, this property contains a value of -1 because the stack
186 is initially empty.
187
188 \sa currentWidget(), indexOf()
189*/
190
191void QStackedWidget::setCurrentIndex(int index)
192{
193 d_func()->layout->setCurrentIndex(index);
194}
195
196int QStackedWidget::currentIndex() const
197{
198 return d_func()->layout->currentIndex();
199}
200
201/*!
202 Returns the current widget, or \nullptr if there are no child widgets.
203
204 \sa currentIndex(), setCurrentWidget()
205*/
206QWidget *QStackedWidget::currentWidget() const
207{
208 return d_func()->layout->currentWidget();
209}
210
211
212/*!
213 \fn void QStackedWidget::setCurrentWidget(QWidget *widget)
214
215 Sets the current widget to be the specified \a widget. The new
216 current widget must already be contained in this stacked widget.
217
218 \sa currentWidget(), setCurrentIndex()
219 */
220void QStackedWidget::setCurrentWidget(QWidget *widget)
221{
222 Q_D(QStackedWidget);
223 if (Q_UNLIKELY(d->layout->indexOf(widget) == -1)) {
224 qWarning(msg: "QStackedWidget::setCurrentWidget: widget %p not contained in stack", widget);
225 return;
226 }
227 d->layout->setCurrentWidget(widget);
228}
229
230/*!
231 Returns the index of the given \a widget, or -1 if the given \a
232 widget is not a child of the QStackedWidget.
233
234 \sa currentIndex(), widget()
235*/
236int QStackedWidget::indexOf(const QWidget *widget) const
237{
238 return d_func()->layout->indexOf(widget);
239}
240
241/*!
242 Returns the widget at the given \a index, or \nullptr if there is
243 no such widget.
244
245 \sa currentWidget(), indexOf()
246*/
247QWidget *QStackedWidget::widget(int index) const
248{
249 return d_func()->layout->widget(index);
250}
251
252/*!
253 \property QStackedWidget::count
254 \brief the number of widgets contained by this stacked widget
255
256 By default, this property contains a value of 0.
257
258 \sa currentIndex(), widget()
259*/
260int QStackedWidget::count() const
261{
262 return d_func()->layout->count();
263}
264
265/*! \reimp */
266bool QStackedWidget::event(QEvent *e)
267{
268 return QFrame::event(e);
269}
270
271QT_END_NAMESPACE
272
273#include "moc_qstackedwidget.cpp"
274

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