PDA

View Full Version : Exchanging a widget in a four way split with QSplitter



Cruz
9th February 2014, 01:45
I used QSplitters in a layout to split up my screen in four parts like so:

10025

The horizontal splitter "contains" two vertical splitters



verticalSplitterTop = new QSplitter();
verticalSplitterTop->addWidget(&configWidget);
verticalSplitterTop->addWidget(&landscapeWidget);

verticalSplitterBottom = new QSplitter(ui.centralWidget);
verticalSplitterBottom->addWidget(&checkboxWidget);
verticalSplitterBottom->addWidget(&graphWidget);

horizontalSplitter = new QSplitter(Qt::Vertical);
horizontalSplitter->addWidget(verticalSplitterTop);
horizontalSplitter->addWidget(verticalSplitterBottom);

centralLayout->addWidget(horizontalSplitter);



and the vertical splitters are synchronized so that if one is dragged, the other one moves the same way.




connect(verticalSplitterTop, SIGNAL(splitterMoved(int, int)), this, SLOT(topSplitterMoved()));
connect(verticalSplitterBottom, SIGNAL(splitterMoved(int, int)), this, SLOT(bottomSplitterMoved()));

// Vertical splitter synchronization.
void CaptureStepFramework::topSplitterMoved()
{
verticalSplitterBottom->setSizes(verticalSplitterTop->sizes());
}
void CaptureStepFramework::bottomSplitterMoved()
{
verticalSplitterTop->setSizes(verticalSplitterBottom->sizes());
}


This is to make the splitters behave like a cross. It does the job but it doesn't always look pretty. Anyhow. Now I would like to exchange the widget in the top right corner by the press of a button, and since I can't find a way to remove a widget from a splitter and to replace it with another one, I see myself forced to reconstruct the whole cross.



void CaptureStepFramework::toggleMainWidget()
{
bool w = false;
if (verticalSplitterTop->widget(1) == &limpWidget)
w = true;

verticalSplitterTop = new QSplitter();
verticalSplitterTop->addWidget(&configWidget);
if (w)
verticalSplitterTop->addWidget(&landscapeWidget);
else
verticalSplitterTop->addWidget(&limpWidget);
verticalSplitterTop->setSizes(verticalSplitterBottom->sizes());

QLayout* centralLayout = ui.centralWidget->layout();
centralLayout->removeWidget(horizontalSplitter);

horizontalSplitter = new QSplitter(Qt::Vertical, ui.centralWidget);
horizontalSplitter->addWidget(verticalSplitterTop);
horizontalSplitter->addWidget(verticalSplitterBottom);
centralLayout->addWidget(horizontalSplitter);

connect(verticalSplitterTop, SIGNAL(splitterMoved(int, int)), this, SLOT(topSplitterMoved()));
}



This also does the job, but the result is ugly. The top left widget disappears for a moment. I also don't think that this code cleans up properly, but my experiments with deleteLater() or just delete things were fatal. Can anyone help me with doing this properly?

Thanks
Cruz

anda_skoa
9th February 2014, 13:56
I see two options:

1) if you don't need to destroy the two widgets that are displayed in the top right cell, use a QStackedWidget to which you add both. Then use setCurrentIndex() or setCurrentWidget() for toggling

2) if you need to delete the widget that is currently not displayed, add an empty QWidget to the "grid" and have the current widget as its only child.

Cheers,
_

Cruz
9th February 2014, 19:38
QStackedWidget works like a charm.