1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the gui module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qstackedlayout.h"
30
#include "qlayout_p.h"
35
class QStackedLayoutPrivate : public QLayoutPrivate
37
Q_DECLARE_PUBLIC(QStackedLayout)
39
QStackedLayoutPrivate() : index(-1) {}
40
QList<QLayoutItem *> list;
47
\brief The QStackedLayout class provides a stack of widgets where
48
only one widget is visible at a time.
50
\ingroup geomanagement
54
QStackedLayout can be used to create a user interface similar to
55
the one provided by QTabWidget. There is also a convenience
56
QStackedWidget class built on top of QStackedLayout.
58
A QStackedLayout can be populated with a number of child widgets
62
QWidget *firstPageWidget = new QWidget;
63
QWidget *secondPageWidget = new QWidget;
64
QWidget *thirdPageWidget = new QWidget;
67
QStackedLayout *layout = new QStackedLayout;
68
layout->addWidget(firstPageWidget);
69
layout->addWidget(secondPageWidget);
70
layout->addWidget(thirdPageWidget);
74
When inserted, the widgets are added to an internal list. The
75
indexOf() function returns the index of a widget in that list.
76
The widget() function returns the widget at a given index
77
position. The index of the widget that is shown on screen is
78
given by currentIndex() and can be changed using setCurrentIndex().
80
QStackedLayout provides no intrinsic means for the user to switch
81
page. This is typically done through a QComboBox or a QListWidget
82
that stores the titles of the QStackedLayout's pages. For
86
QComboBox *pageComboBox = new QComboBox;
87
pageComboBox->addItem(tr("Page 1"));
88
pageComboBox->addItem(tr("Page 2"));
89
pageComboBox->addItem(tr("Page 3"));
90
connect(pageComboBox, SIGNAL(activated(int)),
91
layout, SLOT(setCurrentIndex(int)));
94
\sa QStackedWidget, QTabWidget
98
\fn void QStackedLayout::currentChanged(int index)
100
This signal is emitted when the current widget in the layout changes.
101
The \a index specifies the index of the new current widget.
103
\sa currentWidget(), setCurrentWidget()
107
\fn void QStackedLayout::widgetRemoved(int index)
109
This signal is emitted when the widget at position \a index
110
is removed from the layout.
116
Constructs a QStackedLayout with no parent.
118
This QStackedLayout must be added to another layout later on to
121
QStackedLayout::QStackedLayout()
122
: QLayout(*new QStackedLayoutPrivate, 0, 0)
127
Constructs a new QStackedLayout with the given \a parent.
129
This layout will install itself on the \a parent widget and
130
manage the geometry of its children.
132
QStackedLayout::QStackedLayout(QWidget *parent)
133
: QLayout(*new QStackedLayoutPrivate, 0, parent)
138
Constructs a new QStackedLayout and inserts it into
139
the given \a parentLayout.
141
QStackedLayout::QStackedLayout(QLayout *parentLayout)
142
: QLayout(*new QStackedLayoutPrivate, parentLayout, 0)
147
Destroys this QStackedLayout.
149
The layout's widgets are \e not destroyed.
151
QStackedLayout::~QStackedLayout()
158
Adds \a widget to the end of this layout and returns the
159
index position of \a widget.
161
If the QStackedLayout is empty before this function is called,
162
\a widget becomes the current widget.
164
\sa insertWidget(), removeWidget(), currentWidget()
166
int QStackedLayout::addWidget(QWidget *widget)
169
return insertWidget(d->list.count(), widget);
173
Inserts \a widget at position \a index in this QStackedLayout. If
174
\a index is out of range, the widget is appended. Returns the
175
actual index of \a widget.
177
If the QStackedLayout is empty before this function is called,
178
\a widget becomes the current widget.
182
int QStackedLayout::insertWidget(int index, QWidget *widget)
185
addChildWidget(widget);
186
index = qMin(index, d->list.count());
188
index = d->list.count();
189
QWidgetItem *wi = new QWidgetItem(widget);
190
d->list.insert(index, wi);
193
setCurrentIndex(index);
204
QLayoutItem *QStackedLayout::itemAt(int index) const
206
Q_D(const QStackedLayout);
207
return d->list.value(index);
213
QLayoutItem *QStackedLayout::takeAt(int index)
216
if (index <0 || index >= d->list.size())
218
QLayoutItem *item = d->list.takeAt(index);
219
if (index == d->index) {
221
if ( d->list.count() > 0 ) {
222
int newIndex = index > 0 ? index - 1 : 0;
223
setCurrentIndex(newIndex);
225
} else if (index < d->index) {
228
emit widgetRemoved(index);
233
\property QStackedLayout::currentIndex
234
\brief the index position of the widget that is visible
236
The current index is -1 if there is no current widget.
238
\sa currentWidget(), indexOf()
240
void QStackedLayout::setCurrentIndex(int index)
243
QWidget *prev = currentWidget();
244
QWidget *next = widget(index);
245
if (!next || next == prev)
248
bool reenableUpdates = false;
249
QWidget *parent = parentWidget();
251
if (parent && parent->updatesEnabled()) {
252
reenableUpdates = true;
253
parent->setUpdatesEnabled(false);
260
// try to move focus onto the incoming widget if focus
261
// was somewhere on the outgoing widget.
264
QWidget * fw = parent->window()->focusWidget();
265
if (prev->isAncestorOf(fw)) { // focus was on old page
266
// look for the best focus widget we can find
267
if (QWidget *nfw = next->focusWidget())
270
// second best: first child widget in the focus chain
272
while ((i = i->nextInFocusChain()) != fw) {
273
if (((i->focusPolicy() & Qt::TabFocus) == Qt::TabFocus)
274
&& !i->focusProxy() && i->isVisibleTo(next) && i->isEnabled()
275
&& next->isAncestorOf(i)) {
280
// third best: incoming widget
289
parent->setUpdatesEnabled(true);
290
emit currentChanged(index);
293
int QStackedLayout::currentIndex() const
295
Q_D(const QStackedLayout);
301
\fn void QStackedLayout::setCurrentWidget(QWidget *widget)
303
Sets the current widget to the \a widget specified. The new widget
304
must already be contained in this stacked layout.
306
\sa setCurrentIndex(), currentWidget()
308
void QStackedLayout::setCurrentWidget(QWidget *widget)
310
Q_ASSERT_X(indexOf(widget) >= 0, "QStackedLayout::setCurrentWidget", "widget not contained in stack");
311
setCurrentIndex(indexOf(widget));
316
Returns the current widget, or 0 if there are no widgets in this
319
Equivalent to widget(currentIndex()).
323
QWidget *QStackedLayout::currentWidget() const
325
Q_D(const QStackedLayout);
326
return d->index >= 0 ? d->list.at(d->index)->widget() : 0;
330
Returns the widget at position \a index, or 0 if there is no
331
widget at the given position.
333
\sa currentWidget(), indexOf()
335
QWidget *QStackedLayout::widget(int index) const
337
Q_D(const QStackedLayout);
338
if (index < 0 || index >= d->list.size())
340
return d->list.at(index)->widget();
344
\property QStackedLayout::count
345
\brief the number of widgets contained in the layout
347
int QStackedLayout::count() const
349
Q_D(const QStackedLayout);
350
return d->list.size();
357
void QStackedLayout::addItem(QLayoutItem *item)
359
QWidget *widget = item->widget();
364
qWarning("QStackedLayout::addItem: Only widgets can be added");
371
QSize QStackedLayout::sizeHint() const
373
Q_D(const QStackedLayout);
375
int n = d->list.count();
377
for (int i = 0; i < n; ++i)
378
if (QWidget *widget = d->list.at(i)->widget())
379
s = s.expandedTo(widget->sizeHint());
386
QSize QStackedLayout::minimumSize() const
388
Q_D(const QStackedLayout);
390
int n = d->list.count();
392
for (int i = 0; i < n; ++i)
393
if (QWidget *widget = d->list.at(i)->widget())
394
s = s.expandedTo(widget->minimumSizeHint());
401
void QStackedLayout::setGeometry(const QRect &rect)
403
QWidget *widget = currentWidget();
405
widget->setGeometry(rect);