Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qstackedlayout.cpp
Go to the documentation of this file.
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 "qstackedlayout.h"
5#include "qlayout_p.h"
6
7#include <qlist.h>
8#include "private/qwidget_p.h"
9#include "private/qlayoutengine_p.h"
10
11#include <memory>
12
14
16{
17 Q_DECLARE_PUBLIC(QStackedLayout)
18public:
20 QLayoutItem* replaceAt(int index, QLayoutItem *newitem) override;
22 int index;
24};
25
27{
28 Q_Q(QStackedLayout);
29 if (idx < 0 || idx >= list.size() || !newitem)
30 return nullptr;
31 QWidget *wdg = newitem->widget();
32 if (Q_UNLIKELY(!wdg)) {
33 qWarning("QStackedLayout::replaceAt: Only widgets can be added");
34 return nullptr;
35 }
36 QLayoutItem *orgitem = list.at(idx);
37 list.replace(idx, newitem);
38 if (idx == index)
39 q->setCurrentIndex(index);
40 return orgitem;
41}
42
124{
125}
126
135{
136}
137
143 : QLayout(*new QStackedLayoutPrivate, parentLayout, nullptr)
144{
145}
146
152{
153 Q_D(QStackedLayout);
154 qDeleteAll(d->list);
155}
156
167{
168 Q_D(QStackedLayout);
169 return insertWidget(d->list.size(), widget);
170}
171
187{
188 Q_D(QStackedLayout);
190 index = qMin(index, d->list.size());
191 if (index < 0)
192 index = d->list.size();
194 d->list.insert(index, wi);
195 invalidate();
196 if (d->index < 0) {
198 } else {
199 if (index <= d->index)
200 ++d->index;
201 if (d->stackingMode == StackOne)
202 widget->hide();
203 widget->lower();
204 }
205 return index;
206}
207
212{
213 Q_D(const QStackedLayout);
214 return d->list.value(index);
215}
216
217// Code that enables proper handling of the case that takeAt() is
218// called somewhere inside QObject destructor (can't call hide()
219// on the object then)
220static bool qt_wasDeleted(const QWidget *w)
221{
223}
224
225
230{
231 Q_D(QStackedLayout);
232 if (index <0 || index >= d->list.size())
233 return nullptr;
234 QLayoutItem *item = d->list.takeAt(index);
235 if (index == d->index) {
236 d->index = -1;
237 if ( d->list.size() > 0 ) {
238 int newIndex = (index == d->list.size()) ? index-1 : index;
239 setCurrentIndex(newIndex);
240 } else {
242 }
243 } else if (index < d->index) {
244 --d->index;
245 }
247 if (item->widget() && !qt_wasDeleted(item->widget()))
248 item->widget()->hide();
249 return item;
250}
251
261{
262 Q_D(QStackedLayout);
263 QWidget *prev = currentWidget();
265 if (!next || next == prev)
266 return;
267
268 bool reenableUpdates = false;
270
271 if (parent && parent->updatesEnabled()) {
272 reenableUpdates = true;
273 parent->setUpdatesEnabled(false);
274 }
275
276 QPointer<QWidget> fw = parent ? parent->window()->focusWidget() : nullptr;
277 const bool focusWasOnOldPage = fw && (prev && prev->isAncestorOf(fw));
278
279 if (prev) {
280 prev->clearFocus();
281 if (d->stackingMode == StackOne)
282 prev->hide();
283 }
284
285 d->index = index;
286 next->raise();
287 next->show();
288
289 // try to move focus onto the incoming widget if focus
290 // was somewhere on the outgoing widget.
291
292 if (parent) {
293 if (focusWasOnOldPage) {
294 // look for the best focus widget we can find
295 if (QWidget *nfw = next->focusWidget())
296 nfw->setFocus();
297 else {
298 // second best: first child widget in the focus chain
299 if (QWidget *i = fw) {
300 while ((i = i->nextInFocusChain()) != fw) {
301 if (((i->focusPolicy() & Qt::TabFocus) == Qt::TabFocus)
302 && !i->focusProxy() && i->isVisibleTo(next) && i->isEnabled()
303 && next->isAncestorOf(i)) {
304 i->setFocus();
305 break;
306 }
307 }
308 // third best: incoming widget
309 if (i == fw )
310 next->setFocus();
311 }
312 }
313 }
314 }
315 if (reenableUpdates)
316 parent->setUpdatesEnabled(true);
318}
319
321{
322 Q_D(const QStackedLayout);
323 return d->index;
324}
325
326
336{
337 int index = indexOf(widget);
338 if (Q_UNLIKELY(index == -1)) {
339 qWarning("QStackedLayout::setCurrentWidget: Widget %p not contained in stack", widget);
340 return;
341 }
343}
344
345
353{
354 Q_D(const QStackedLayout);
355 return d->index >= 0 ? d->list.at(d->index)->widget() : nullptr;
356}
357
365{
366 Q_D(const QStackedLayout);
367 if (index < 0 || index >= d->list.size())
368 return nullptr;
369 return d->list.at(index)->widget();
370}
371
379{
380 Q_D(const QStackedLayout);
381 return d->list.size();
382}
383
384
389{
390 std::unique_ptr<QLayoutItem> guard(item);
391 QWidget *widget = item->widget();
392 if (Q_UNLIKELY(!widget)) {
393 qWarning("QStackedLayout::addItem: Only widgets can be added");
394 return;
395 }
397}
398
403{
404 Q_D(const QStackedLayout);
405 QSize s(0, 0);
406 int n = d->list.size();
407
408 for (int i = 0; i < n; ++i)
409 if (QWidget *widget = d->list.at(i)->widget()) {
410 QSize ws(widget->sizeHint());
412 ws.setWidth(0);
414 ws.setHeight(0);
415 s = s.expandedTo(ws);
416 }
417 return s;
418}
419
424{
425 Q_D(const QStackedLayout);
426 QSize s(0, 0);
427 int n = d->list.size();
428
429 for (int i = 0; i < n; ++i)
430 if (QWidget *widget = d->list.at(i)->widget())
431 s = s.expandedTo(qSmartMinSize(widget));
432 return s;
433}
434
439{
440 Q_D(QStackedLayout);
441 switch (d->stackingMode) {
442 case StackOne:
445 break;
446 case StackAll:
447 if (const int n = d->list.size())
448 for (int i = 0; i < n; ++i)
449 if (QWidget *widget = d->list.at(i)->widget())
451 break;
452 }
453}
454
459{
460 const int n = count();
461
462 for (int i = 0; i < n; ++i) {
463 if (QLayoutItem *item = itemAt(i)) {
464 if (item->hasHeightForWidth())
465 return true;
466 }
467 }
468 return false;
469}
470
475{
476 const int n = count();
477
478 int hfw = 0;
479 for (int i = 0; i < n; ++i) {
480 if (QLayoutItem *item = itemAt(i)) {
481 if (QWidget *w = item->widget())
482 /*
483 Note: Does not query the layout item, but bypasses it and asks the widget
484 directly. This is consistent with how QStackedLayout::sizeHint() is
485 implemented. This also avoids an issue where QWidgetItem::heightForWidth()
486 returns -1 if the widget is hidden.
487 */
488 hfw = qMax(hfw, w->heightForWidth(width));
489 }
490 }
491 hfw = qMax(hfw, minimumSize().height());
492 return hfw;
493}
494
522{
523 Q_D(const QStackedLayout);
524 return d->stackingMode;
525}
526
528{
529 Q_D(QStackedLayout);
530 if (d->stackingMode == stackingMode)
531 return;
532 d->stackingMode = stackingMode;
533
534 const int n = d->list.size();
535 if (n == 0)
536 return;
537
538 switch (d->stackingMode) {
539 case StackOne:
540 if (const int idx = currentIndex())
541 for (int i = 0; i < n; ++i)
542 if (QWidget *widget = d->list.at(i)->widget())
543 widget->setVisible(i == idx);
544 break;
545 case StackAll: { // Turn overlay on: Make sure all widgets are the same size
547 if (const QWidget *widget = currentWidget())
549 for (int i = 0; i < n; ++i)
550 if (QWidget *widget = d->list.at(i)->widget()) {
551 if (!geometry.isNull())
553 widget->setVisible(true);
554 }
555 }
556 break;
557 }
558}
559
561
562#include "moc_qstackedlayout.cpp"
void hide()
Hides the item (items are visible by default).
The QLayoutItem class provides an abstract item that a QLayout manipulates.
Definition qlayoutitem.h:25
virtual QWidget * widget() const
If this item manages a QWidget, returns that widget.
static QWidgetItem * createWidgetItem(const QLayout *layout, QWidget *widget)
Definition qlayout.cpp:148
The QLayout class is the base class of geometry managers.
Definition qlayout.h:26
QRect geometry() const override
\reimp
Definition qlayout.cpp:460
void addChildWidget(QWidget *w)
This function is called from addWidget() functions in subclasses to add w as a managed widget of a la...
Definition qlayout.cpp:836
void invalidate() override
\reimp
Definition qlayout.cpp:469
QWidget * parentWidget() const
Returns the parent widget of this layout, or \nullptr if this layout is not installed on any widget.
Definition qlayout.cpp:399
virtual int indexOf(const QWidget *) const
Searches for widget widget in this layout (not including child layouts).
Definition qlayout.cpp:1176
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
void replace(qsizetype i, parameter_type t)
Definition qlist.h:526
uint wasDeleted
Definition qobject.h:66
static QObjectPrivate * get(QObject *o)
Definition qobject_p.h:153
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
\inmodule QtCore
Definition qpointer.h:18
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr bool isNull() const noexcept
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition qrect.h:163
constexpr Policy verticalPolicy() const noexcept
Returns the vertical component of the size policy.
Definition qsizepolicy.h:67
constexpr Policy horizontalPolicy() const noexcept
Returns the horizontal component of the size policy.
Definition qsizepolicy.h:66
\inmodule QtCore
Definition qsize.h:25
QLayoutItem * replaceAt(int index, QLayoutItem *newitem) override
QList< QLayoutItem * > list
QStackedLayout::StackingMode stackingMode
The QStackedLayout class provides a stack of widgets where only one widget is visible at a time.
void widgetRemoved(int index)
This signal is emitted whenever a widget is removed from the layout.
StackingMode stackingMode
determines the way visibility of child widgets are handled.
void setCurrentIndex(int index)
int heightForWidth(int width) const override
\reimp
QSize minimumSize() const override
\reimp
void setStackingMode(StackingMode stackingMode)
QLayoutItem * itemAt(int) const override
\reimp
int insertWidget(int index, QWidget *w)
Inserts the given widget at the given index in this QStackedLayout.
bool hasHeightForWidth() const override
\reimp
void currentChanged(int index)
This signal is emitted whenever the current widget in the layout changes.
int currentIndex
the index position of the widget that is visible
int addWidget(QWidget *w)
Adds the given widget to the end of this layout and returns the index position of the widget.
void setGeometry(const QRect &rect) override
\reimp
void setCurrentWidget(QWidget *w)
Sets the current widget to be the specified widget.
QWidget * currentWidget() const
Returns the current widget, or \nullptr if there are no widgets in this layout.
~QStackedLayout()
Destroys this QStackedLayout.
QStackedLayout()
Constructs a QStackedLayout with no parent.
void addItem(QLayoutItem *item) override
\reimp
QLayoutItem * takeAt(int) override
\reimp
QSize sizeHint() const override
\reimp
int count() const override
the number of widgets contained in the layout
The QWidgetItem class is a layout item that represents a widget.
Definition qlayoutitem.h:86
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setGeometry(int x, int y, int w, int h)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qwidget.h:886
void clearFocus()
Takes keyboard input focus from the widget.
Definition qwidget.cpp:6706
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition qwidget.h:106
QSizePolicy sizePolicy
the default layout behavior of the widget
Definition qwidget.h:119
void hide()
Hides the widget.
Definition qwidget.cpp:8209
virtual void setVisible(bool visible)
Definition qwidget.cpp:8329
void lower()
Lowers the widget to the bottom of the parent widget's stack.
QSize sizeHint
the recommended size for the widget
Definition qwidget.h:148
bool isAncestorOf(const QWidget *child) const
Returns true if this widget is a parent, (or grandparent and so on to any level), of the given child,...
Definition qwidget.cpp:8868
QOpenGLWidget * widget
[1]
qDeleteAll(list.begin(), list.end())
rect
[4]
short next
Definition keywords.cpp:445
Combined button and popup list for selecting options.
@ TabFocus
Definition qnamespace.h:107
#define Q_UNLIKELY(x)
Q_WIDGETS_EXPORT QSize qSmartMinSize(const QSize &sizeHint, const QSize &minSizeHint, const QSize &minSize, const QSize &maxSize, const QSizePolicy &sizePolicy)
#define qWarning
Definition qlogging.h:162
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLuint index
[2]
GLint GLsizei width
GLfloat n
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLdouble s
[6]
Definition qopenglext.h:235
static bool qt_wasDeleted(const QWidget *w)
#define emit
QObject::connect nullptr
QGraphicsItem * item
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent