PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [C++/Qt4.2] Layout-Manager ändern bzw. Widget aus Layout löschen?


Expandable
2007-04-12, 16:31:29
Hallo allerseits,

ich habe hier ein Problem mit Qt 4.2, wo ich gerade dran verzweifle. Nehmen wir an, wir haben eine Klasse die von QWidget erbt. Der Konstruktor führt sinngemäß folgenden Code aus:


QHBoxLayout* l = new QHBoxLayout();
QLabel* label = new QLabel("Hi");
l->addWidget(label);
setLayout(l);


Somit haben wir also ein QHBoxLayout, das nur ein Label enthält und als Layout-Manager des Widgets gesetzt wird. In einer späteren Funktion würde ich nun gerne einen anderen Layout-Manager installieren. In der Qt-Dokumentation steht - und der Qt-Sourcecode bestätigt dies ;) - dass man keinen neuen Layout-Manager setzen kann, bevor der alte nicht gelöscht ist. Doch wie lösche ich den alten Layout-Manager? QWidget::layout() liefert mir bloß einen Pointer darauf zurück, löscht man diesen, so hat dies keine Wirkung (und scheint mir potenziell gefährlich zu sein).

Nun dachte ich mir, gut, was soll's, lassen wir den Layout-Manager halt drinnen. Nun würde ich gern das Label aus dem Layout-Manager löschen und durch einen anderen Layout-Manager ersetzen. Um ein Widget zu löschen, gibt's die Funktionen removeWidget(QWidget*) und takeAt(int position). Beides hat jedoch keinerlei Auswirkung, das Widget wird nach wie vor angezeigt (auch ein deleten des Widget-Pointers bringt wieder nichts).

Wobei in der Qt-Doku sogar noch steht:


// The following code fragment shows a safe way to remove all items from a layout:

QLayoutItem *child;
while ((child = layout->takeAt(0)) != 0) {
...
delete child;
}


Nur bei mir leider nicht. Es hat keine Auswirkung.

Hier mal mein derzeitiger Code für das "Widget-Replacement", wobei ich hier nun gleich ein QGridLayout verwende und gar nicht mehr versuche, den Layout-Manager zu ersetzen:


void MyWidget::createHelpMessage()
{
QLabel* helpLabel = new QLabel(tr("blablabla"));

QGridLayout* layout = new QGridLayout();
layout->addWidget(helpLabel, 0, 0);
setLayout(layout);
}

void MyWidget::setupResultTable()
{
// Clear current layout
QGridLayout* grid = dynamic_cast<QGridLayout* >(layout());
QLayoutItem* child = 0;
while ((child = grid->takeAt(0)) != 0)
delete child;

// Add new data
for (int row = 0; row < m_algorithmData.count(); ++row)
{
for (int col = 0; col < 8; ++col)
{
QLabel* l = new QLabel(QString::number(m_algorithmData.at(row).values[col]));
grid->addWidget(l, row, col);
}
}

grid->invalidate();
}


Schon mal danke für eure Hilfe... es kann ja wohl nicht so schwer sein, einen Layout-Manager/Widget zu löschen. Ich seh's nur grad einfach nicht, und die Qt-Doku sowie eine Google(-Groups)-Suche halfen mir nicht weiter...

Backe
2007-04-12, 19:55:31
void MyWidget::setupLayout_1()
{
QLayout *old_layout = layout();

hide();

delete old_layout;

QVBoxLayout *vbox_layout = new QVBoxLayout();

vbox_layout->addWidget(label_1);

vbox_layout->addWidget(layout_1_button);
vbox_layout->addWidget(layout_2_button);

setLayout(vbox_layout);

show();
}

...hat bei mir funktioniert, aber auch erst nachdem ich hide() und show() eingefügt habe.

Expandable
2007-04-13, 00:10:13
Danke, aber geht trotzdem nicht... das alte Layout bleibt einfach erhalten.... ich versteh's nicht...

Expandable
2007-04-14, 21:16:47
Hat niemand eine Idee? Irgendwelche Workarounds?? Hat sonst keiner das Problem? Ich konnte es bislang noch nicht lösen...

Danke...

Expandable
2007-04-27, 13:37:45
Also falls es jemanden interessiert, ich konnte das Problem wie folgt lösen, und zwar mit Hilfe des QStackedLayouts:


void MyWidget::createHelpMessage()
{
QLabel* helpLabel = new QLabel(tr("Hilfe! Hilfe!"));

QHBoxLayout* mainLayout = new QHBoxLayout();
QFrame* frame = new QFrame();

QHBoxLayout* layout = new QHBoxLayout();
layout->addStretch();
layout->addWidget(helpLabel, 0, 0);
layout->addStretch();

m_layout = new QStackedLayout();
frame->setLayout(layout);
m_layout->addWidget(frame);

mainLayout->addLayout(m_layout);
setLayout(mainLayout);
}

void MyWidget::setupResultTable()
{
if (m_layout->count() == 2)
{
QFrame* frame = dynamic_cast<QFrame* >(m_layout->takeAt(1)->widget());
if (frame != 0) // if frame == 0, just don't do anything, shouldn't happen anyway
{
qDeleteAll(frame->children());
delete frame->layout();
}
}

QFrame* frame = new QFrame();

QGridLayout* grid = new QGridLayout(frame);
for (int row = 0; row < m_algorithmData.count(); ++row)
{
for (int col = 0; col < 8; ++col)
{
QLabel* l = new QLabel(QString::number(m_algorithmData.at(row).values[col]), frame);
grid->addWidget(l, row, col);
}
}

frame->setLayout(grid);
m_layout->addWidget(frame);
m_layout->setCurrentIndex(1);