summaryrefslogtreecommitdiffstats
path: root/src/widgets/widgets/qsplitter.cpp
diff options
context:
space:
mode:
authorGabriel de Dietrich <gabriel.dedietrich@qt.io>2016-11-16 17:21:32 -0800
committerGabriel de Dietrich <gabriel.dedietrich@qt.io>2016-12-02 16:15:58 +0000
commit2c634a132696376a0a0d7641bf05ae875c50190e (patch)
tree828b10cad212ca4f320c4b6a012ddc660a023e7a /src/widgets/widgets/qsplitter.cpp
parent9f2f3cb90b211b273139e12640d36f6ce845dc98 (diff)
Introducing QSplitter::replaceWidget()
This new API addresses the use case where we want to replace a widget by another one inside the splitter. Up to now, the way of doing would include removing one widget and add the new one at the same place. However, this triggers a series of resize and paint events because of the successive changes in the splitter's children leading to a relayout of the remaining children. The new widget inherits the same properties as in the previous slot: geometry, visibility, and collapsed states. The previous widget, returned by the function, loses its parent and is hidden. Change-Id: I3dddf6b582d5ce2db8cff3c40bc46084263123ac Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Diffstat (limited to 'src/widgets/widgets/qsplitter.cpp')
-rw-r--r--src/widgets/widgets/qsplitter.cpp71
1 files changed, 68 insertions, 3 deletions
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 910904e96e..77a793e951 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -731,6 +731,12 @@ void QSplitterPrivate::setSizes_helper(const QList<int> &sizes, bool clampNegati
doResize();
}
+bool QSplitterPrivate::shouldShowWidget(const QWidget *w) const
+{
+ Q_Q(const QSplitter);
+ return q->isVisible() && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide));
+}
+
void QSplitterPrivate::setGeo(QSplitterLayoutStruct *sls, int p, int s, bool allowCollapse)
{
Q_Q(QSplitter);
@@ -827,8 +833,7 @@ void QSplitterPrivate::insertWidget_helper(int index, QWidget *widget, bool show
{
Q_Q(QSplitter);
QBoolBlocker b(blockChildAdd);
- bool needShow = show && q->isVisible() &&
- !(widget->isHidden() && widget->testAttribute(Qt::WA_WState_ExplicitShowHide));
+ const bool needShow = show && shouldShowWidget(widget);
if (widget->parentWidget() != q)
widget->setParent(q);
if (needShow)
@@ -1125,6 +1130,66 @@ void QSplitter::insertWidget(int index, QWidget *widget)
}
/*!
+ \since 5.9
+
+ Replaces the widget in the splitter's layout at the given \a index by \a widget.
+
+ Returns the widget that has just been replaced if \a index is valid and \a widget
+ is not already a child of the splitter. Otherwise, it returns null and no replacement
+ or addition is made.
+
+ The geometry of the newly inserted widget will be the same as the widget it replaces.
+ Its visible and collapsed states are also inherited.
+
+ \note The splitter takes ownership of \a widget and sets the parent of the
+ replaced widget to null.
+
+ \sa insertWidget(), indexOf()
+*/
+QWidget *QSplitter::replaceWidget(int index, QWidget *widget)
+{
+ Q_D(QSplitter);
+ if (!widget) {
+ qWarning("QSplitter::replaceWidget: Widget can't be null");
+ return nullptr;
+ }
+
+ if (index < 0 || index >= d->list.count()) {
+ qWarning("QSplitter::replaceWidget: Index %d out of range", index);
+ return nullptr;
+ }
+
+ QSplitterLayoutStruct *s = d->list.at(index);
+ QWidget *current = s->widget;
+ if (current == widget) {
+ qWarning("QSplitter::replaceWidget: Trying to replace a widget with itself");
+ return nullptr;
+ }
+
+ if (widget->parentWidget() == this) {
+ qWarning("QSplitter::replaceWidget: Trying to replace a widget with one of its siblings");
+ return nullptr;
+ }
+
+ QBoolBlocker b(d->blockChildAdd);
+
+ const QRect geom = current->geometry();
+ const bool shouldShow = d->shouldShowWidget(current);
+
+ s->widget = widget;
+ current->setParent(nullptr);
+ widget->setParent(this);
+
+ // The splitter layout struct's geometry is already set and
+ // should not change. Only set the geometry on the new widget
+ widget->setGeometry(geom);
+ widget->lower();
+ widget->setVisible(shouldShow);
+
+ return current;
+}
+
+/*!
\fn int QSplitter::indexOf(QWidget *widget) const
Returns the index in the splitter's layout of the specified \a widget. This
@@ -1232,7 +1297,7 @@ void QSplitter::childEvent(QChildEvent *c)
if (c->added() && !d->blockChildAdd && !d->findWidget(w)) {
d->insertWidget_helper(d->list.count(), w, false);
} else if (c->polished() && !d->blockChildAdd) {
- if (isVisible() && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide)))
+ if (d->shouldShowWidget(w))
w->show();
} else if (c->type() == QEvent::ChildRemoved) {
for (int i = 0; i < d->list.size(); ++i) {