PDA

View Full Version : Deleting a Qsplitter



Elberion
15th May 2011, 10:53
Hi, i have a glwidget that renders a cube. I want to have different views of the cube, and that the user can choose how many views it want.
So if he wants dual view for example:

gridGroupBox = new QGroupBox(tr("Grid layout"));
hbox = new QHBoxLayout(this);
splitter1->addWidget(glWidget);
splitter1->addWidget(topright);
hbox->addWidget(splitter1);

So my question is, how do i remove the splitter to go back to single view?
I tride hide, doesnt work, delete later doesnt work. It should be something like.

hbox->removeWidget(splitter);
hbox->addWidget(glWidget);

That doesn't work because the splitter is still there!
Thank u for ur help!
Elbe

ChrisW67
15th May 2011, 23:22
If a QSplitter contains only one widget, or only one visible widget, then the splitter handle is not shown. The QSplitter still exists, and can have widgets re-added. Watch this for 10 seconds:


#include <QtGui>
#include <QDebug>

class MainWindow: public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *p = 0): QMainWindow(p) {
QSplitter *central = new QSplitter(this);
left = new QLabel("Left", this);
central->addWidget(left);
right = new QLabel("Right", this);
central->addWidget(right);

setCentralWidget(central);

QTimer::singleShot(5000, this, SLOT(removeRight()));
QTimer::singleShot(10000, this, SLOT(restoreRight()));
}
public slots:
void removeRight() {
qDebug() << "removeRight";
right->hide();
// right->deleteLater(); // if you do not need the widget any more
}
void restoreRight() {
qDebug() << "restoreRight";
right->show();
}
private:
QLabel *left;
QLabel *right;
};

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

MainWindow m;
m.show();
return app.exec();
}
#include "main.moc"

If you really want the splitter to go away entirely then (in this example):


void removeSplitter() {
qDebug() << "removeSplitter";
setCentralWidget(left);
splitter->deleteLater();
right->deleteLater();
}

Elberion
16th May 2011, 14:03
Thank you very much Chris!
I realized that i was doing splitter.hide() instead of the widgets in the splitter.
So i have 4 views of my scene topleft,topright, botleft and botright.
Single view shows topleft. Dual view shows topleft and topright. Quad view shows all 4.

With your help i can switch now between dual and single view without problem. But when i go into Quad view , Debug shows:
QLayout: Attempting to add QLayout "" to MainWindow "", which already has a layout
and the execution of my program stops.

Why would that be? What am i missing?

Here is part of my code

//In Constructor


glWidget = new GLWidget(1);
topright = new GLWidget(2);
botleft = new GLWidget(3);
botright = new GLWidget(4);

old_view=1;
gridGroupBox = new QGroupBox(tr("Grid layout"));
hbox = new QHBoxLayout(this);

splitter1 = new QSplitter(Qt::Horizontal, this);
splitter2 = new QSplitter(Qt::Horizontal, this);
splitter3 = new QSplitter(Qt::Vertical, this);

splitter1->addWidget(glWidget);
splitter1->addWidget(topright);
topright->hide();
splitter2->addWidget(botleft);
splitter2->addWidget(botright);
botleft->hide();
botright->hide();
splitter3->addWidget(splitter1);
splitter3->addWidget(splitter2);
splitter2->hide();

hbox->addWidget(splitter3);
gridGroupBox->setLayout(hbox);
setCentralWidget(gridGroupBox);


//Slots


void MainWindow::setSingleV()
{
if(old_view==2)
{
topright->hide();

}else if(old_view==4)
{
topright->hide();
botleft->hide();
botright->hide();
splitter2->hide();
}
old_view=1;
}
void MainWindow::setDualView()
{
if(old_view==1)
{
topright->show();
}else if(old_view==4)
{
botleft->hide();
botright->hide();
splitter2->hide();
}
old_view=2;
}
void MainWindow::setQuadView()
{
if(old_view==1)
{
topright->show();
botleft->show();
botright->show();
splitter2->show();

}else if(old_view==2)
{
botleft->show();
botright->show();
splitter2->show();
}
old_view=4;
}

Thank u very much for ur time!
Elbe

ChrisW67
17th May 2011, 00:21
The warning message about layouts comes about because at line 8 of the constructor you create the layout with the QMainWindow as its parent. When you later add the layout to that window it see that there is already a child layout and informs you (not considering that it is the same layout). This is non-fatal and can be avoided by removing "this" from line 8 (and moving it closer to where it is used at 25).

Nothing else I can see in your code snippets is program life threatening.

What does "my program stops" mean? Crashes with a backtrace in your debugger? Where is the crash originating?

On a widget juggling note... You never need to hide the lower widgets individually: just hide their parent splitter and let them inherit visibility.

Edit:
Make sure that you are not still using deleteLater() on the widgets or splitters and later trying to dereference an invalid pointer.

Elberion
17th May 2011, 16:59
Oh Chris it works so lovely.

I just move what you just said with the layout and voilà !

Thank you very much. It was nagging on me quite a long time!

Regards,

Elberion