VLayout Widget anhand des Index löschen?
VLayout Widget anhand des Index löschen?
Hallo,
wie lösche ich ein Widget aus dem Layout nur mit Hilfe des Index?
_Hab schon in der Doku geschaut und finde keine Möglichkeit...
TakeAt funktioniert nicht...
Viele Grüße
wie lösche ich ein Widget aus dem Layout nur mit Hilfe des Index?
_Hab schon in der Doku geschaut und finde keine Möglichkeit...
TakeAt funktioniert nicht...
Viele Grüße
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Da man eher einen Pointer auf ein Widget hat (man will es ja befüllen etc.) als einen Index zu irgendeinen Layout ist das die korrekte Vorgehensweise.Qt-Doku hat geschrieben: To remove a widget from a layout, call removeWidget(). Calling QWidget::hide() on a widget also effectively removes the widget from the layout until QWidget::show() is called.
MfG Christian
'Funktioniert nicht' ist keine Fehlerbeschreibung
'Funktioniert nicht' ist keine Fehlerbeschreibung
Normalerweise werden Widgets auf dem BoxLayout anhand einer Referenz gelöscht. Sprich du machst dir eine: "QList <QBeliebigesWidget*> ListName;" oder du benutzt den/die Pointer auf das Objekt selbst und rufst dazu "removeWidget(QWidget* name);" auf.
Für die Liste initialisierst du die Widgets dort trägst sie dann in das BoxLayout ein.
Dann kannst du anhand der Listennummer ".at(0)" das Widget aus dem BoxLayout mit "removeWidget(QWidget*)" bzw. mit "removeWidget( ListName.at(0) )" entfernen.
BoxLayout erzeugen zur Laufzeit:
Solltest du nun diesen Code erweitern um die Zeile:
Siehst du, dass der 1. Button nicht mehr in dem Layout ist.
Wenn du es nun noch löschen möchtest erweiterst du um:
Oder änderst den Status:
Das ganze wendest du einfach auf die QList an und alles läuft zu deiner Zufriedenheit.
Für die Liste initialisierst du die Widgets dort trägst sie dann in das BoxLayout ein.
Dann kannst du anhand der Listennummer ".at(0)" das Widget aus dem BoxLayout mit "removeWidget(QWidget*)" bzw. mit "removeWidget( ListName.at(0) )" entfernen.
BoxLayout erzeugen zur Laufzeit:
Code: Alles auswählen
QVBoxLayout* myLayer = new QVBoxLayout(this);
QPushButton* firstBtn = new QPushButton("first",this);
QPushButton* secondBtn = new QPushButton("second",this);
QPushButton* thirdBtn = new QPushButton("third",this);
this->setLayout(myLayer);
myLayer->addWidget(firstBtn);
myLayer->addWidget(secondBtn);
myLayer->addWidget(thirdBtn);Code: Alles auswählen
myLayer->removeWidget(firstBtn);Wenn du es nun noch löschen möchtest erweiterst du um:
Code: Alles auswählen
delete(firstBtn);Code: Alles auswählen
firstBtn->setVisible(false);
//bzw.
firstBtn->hide();Es gibt doch eine Möglichkeit:
Bezogen auf mein Post (Hauptteil+dieser Code hier), entfernt es den ersten Button aus dem BoxLayout.
PS: Grundsätzlich geht man aber davon aus, das man die Refenrenz benutzt, denn diese Methode (s.o.) würde teilweise implizieren, das der Programmierer nicht umbedingt eine Referenz für das Objekt besitzt und weiterhin ist es Problematisch. Wenn zum Beispiel ein anderes Widget dieses überlagert könnte es nach dem entfernen aus dem BoxLayout als Leiche im Programm herumdümpeln. Wollte ich nur mal so anmerken.
Code: Alles auswählen
myLayer->removeItem(myLayer->takeAt(0));PS: Grundsätzlich geht man aber davon aus, das man die Refenrenz benutzt, denn diese Methode (s.o.) würde teilweise implizieren, das der Programmierer nicht umbedingt eine Referenz für das Objekt besitzt und weiterhin ist es Problematisch. Wenn zum Beispiel ein anderes Widget dieses überlagert könnte es nach dem entfernen aus dem BoxLayout als Leiche im Programm herumdümpeln. Wollte ich nur mal so anmerken.
Also bei mir funktioniert das leider nicht...
Das Layout wird zwar geleert aber das Widget bleibt trotzdem erhalten.
n deinem Beispiel der Button, in meinem Programm ein anderes Widget)
Code: Alles auswählen
while(layout->count() > 2) {
QLayoutItem* l = layout->takeAt(2);
layout->removeItem(l);
delete l;
}-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Auch wenn ich immer noch nicht kapiere warum man ein QWidget über den Layoutindex löschen sollte... http://doc.trolltech.com/4.7/qlayoutitem.html#widget
MfG Christian
'Funktioniert nicht' ist keine Fehlerbeschreibung
'Funktioniert nicht' ist keine Fehlerbeschreibung
Geht alles: Mein Code mit deinem in ""richtiger"" Form erweitert ..
Code: Alles auswählen
QVBoxLayout* myLayer = new QVBoxLayout(this);
QPushButton* firstBtn = new QPushButton("first",this);
QPushButton* secondBtn = new QPushButton("second",this);
QPushButton* thirdBtn = new QPushButton("third",this);
this->setLayout(myLayer);
myLayer->addWidget(firstBtn);
myLayer->addWidget(secondBtn);
myLayer->addWidget(thirdBtn);
if(myLayer->count() > 2) {
QLayoutItem* cItem = myLayer->itemAt(2);
myLayer->removeItem(cItem);
QPushButton* cacheBtn = dynamic_cast<QPushButton*>(cItem->widget());
delete(cacheBtn);
delete(cItem);
}Ja delete widget() geht natürlich... aber musste nun doch die Liste nehmen da ich noch einige andere Operationen ausführen musste und ich keine Lust hab ständig zu casten :/
In anderen Frameworks könnte man so etwas schreiben...
Ich würde es nett finden wenn Qt folgendes könnte:
In anderen Frameworks könnte man so etwas schreiben...
Code: Alles auswählen
while (layout.Children.Count > 2)
layout.Children.RemoveAt(2);
Code: Alles auswählen
while (layout->Children.Count() > 2)
delete layout->Children.RemoveAt(2);
Zuletzt geändert von gast23 am 24. Oktober 2010 14:44, insgesamt 1-mal geändert.
In Qt reagieren die Besitzer von QWidgets (Layouts, Tabellen, usw) auf das "destroyed()"-Signal. D.h. ersetze doch einfach:
durch
und fertig...
das Widget aus dem Layout entfernen...
hth..
Code: Alles auswählen
if(myLayer->count() > 2) {
QLayoutItem* cItem = myLayer->itemAt(2);
myLayer->removeItem(cItem);
QPushButton* cacheBtn = dynamic_cast<QPushButton*>(cItem->widget());
delete(cacheBtn);
delete(cItem);
}Code: Alles auswählen
thirdBtn->deleteLater();
Gerade im Prototyping macht es Sinn mit dem Designer zu arbeiten und einer der beiden "Inheritance Approaches" einzusetzen. Gerade in diesem Fall hast du also bereits die Pointer auf die Objekte und kannst z.B. mitgast23 hat geschrieben:Ich gebe zu im C++ Umfeld ist das nicht speichern eines Zeigers schon unsicher... aber im Kontext des Prototypings wo man schnelle Ergebnisse braucht wäre diese Methode sehr hilfreich.
Code: Alles auswählen
ui.btnIrgendwas->deleteLater(); ui.btnIrgendwas=NULL;
hth..
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
Und gerade eben weil sie dynamisch sind - wie kann man dan wissen das an Position 42 das Widget ist welches ich löschen will? Und wie kann man dann die dynamisch erstellten Widgets korrekt befüllen und verändern wenn man keine Pointer oder eindeutige Objektnamen dazu hat etc.? Der Ansatz passt imho irgendwie nicht.
MfG Christian
'Funktioniert nicht' ist keine Fehlerbeschreibung
'Funktioniert nicht' ist keine Fehlerbeschreibung
Naja es gibt schon Fälle...
Annahme: Alle Widgets liegen in dem Container und man kann über den Index einen Zeiger erhalten, dann kannst du doch alles damit tun...
Es geht nicht darum Widget XY zu löschen oder zu kennen sondern allgemein alle Widgets des Containers bzw. ab einem bestimmten Index zu löschen
Annahme: Alle Widgets liegen in dem Container und man kann über den Index einen Zeiger erhalten, dann kannst du doch alles damit tun...
Es geht nicht darum Widget XY zu löschen oder zu kennen sondern allgemein alle Widgets des Containers bzw. ab einem bestimmten Index zu löschen
Dann schreibst du beim Erstellen ja eh Code.. spielt doch keine Rolle ob "Klasse *i = new Klasse()" oder "klList << new Klasse()"...gast23 hat geschrieben:Die Objekte sind dynamisch!
Ist er das? Bei meinen Applikationen wissen die Objekte innerhalt eines Layouts nichts über das Layout.. ein "clicked()" Signal eines Buttons hat ebenso wenig Information über den Index wie ein "textChanged()" - Signal eines LineEdits..gast23 hat geschrieben: Deswegen Index weil der ist praktisch immer bekannt
[EDIT] Christian war schneller