Frage

Ich bin sehr verwirrt über Destruktoren in Qt4 und Hoffnung mit, euch kann mir helfen.
Wenn ich eine Methode wie diese habe (mit „Die“ ist eine Klasse):

void Widget::create() {
    Des *test = new Des;
    test->show();
}

Wie kann ich sicherstellen, dass dieses Widget gelöscht werden soll, nachdem es geschlossen wurde?

Und in der Klasse "Die" Ich habe diese:

Des::Des()
{
    QPushButton *push = new QPushButton("neu");
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(push);
    setLayout(layout);
}

, wo und wie muss ich * push und * Layout löschen? was in dem destructor Des :: ~ Des () enthalten sein sollte?

War es hilfreich?

Lösung

Eine weitere Möglichkeit zur Verwendung von deleteLater() oder Eltern, ist die Lösch-on-close-Funktionalität für Widgets zu verwenden. In diesem Fall wird Qt das Widget löschen, wenn es angezeigt wird getan.

Des *test = new Des;
test->setAttribute( Qt::WA_DeleteOnClose );
test->show();

Ich mag es verwenden, um mit dem Objektbaum, die Qt hält, so dass ich für das Fenster lösche beim Schließen eingestellt, und alle Widgets im Fenster haben ein richtig Eltern angegeben, so dass sie alle als gut gelöscht.

Andere Tipps

Qt verwendet, was sie rufen Sie Objekt Bäume und es ist ein bisschen anders der typische RAII Ansatz.

Die QObject Klasse Konstruktor einen Zeiger auf einen Elternteil QObject nimmt . Wenn das Mutter QObject zerstört wird, werden seine Kinder als auch zerstört werden. Das ist ein ziemlich weit verbreitet Muster über Qt-Klassen und Sie werden eine Menge von Konstrukteuren einen *parent Parameter akzeptieren bemerken.

Wenn Sie auf einige der Beispielprogramme werde feststellen, dass sie tatsächlich die meisten Qt Objekte auf dem Heap konstruieren und Vorteil dieses Objektbaum nehmen Zerstörung zu handhaben. Ich persönlich fand diese Strategie nützlich als auch als GUI-Objekte eigentümliche Lebenszeiten haben können.

Qt stellt keine zusätzliche Garantien über Standard-C ++, wenn Sie nicht QObject oder eine Unterklasse von QObject (wie QWidget) verwendet wird.


In Ihrem speziellen Beispiel gibt es keine Garantie, dass alles gelöscht wird.

Sie so etwas für Des wollen werden (unter der Annahme Des ist eine Unterklasse von QWidget):

class Des : public QWidget
{
    Q_OBJECT

public:
    Des(QWidget* parent)
    : QWidget(parent)
    {
        QPushButton* push = new QPushButton("neu");
        QHBoxLayout* layout = new QHBoxLayout(this);
        layout->addWidget(push); // this re-parents push so layout 
                                 // is the parent of push
        setLayout(layout);
    }

    ~Des()
    {
        // empty, since when Des is destroyed, all its children (in Qt terms)
        // will be destroyed as well
    }
}

Und du würdest Klasse Des verwenden wie folgt:

int someFunction()
{
    // on the heap
    Des* test = new Des(parent); // where parent is a QWidget*
    test->show();
    ...
    // test will be destroyed when its parent is destroyed

    // or on the stack
    Des foo(0);
    foo.show();
    ...
    // foo will fall out of scope and get deleted
}

Richardwb Antwort ist gut - aber der andere Ansatz ist, die deleteLater Slot zu verwenden, etwa so:

Des *test = new Des;
test->show();
connect(test, SIGNAL(closed()), test, SLOT(deleteLater()));

Offensichtlich ist das geschlossen (Signal) mit ausgetauscht werden kann, was auch immer Signal, das Sie wollen.

Dieses Tutorial deutet darauf hin, Sie müssen nicht explizit Widgets löschen, die Eltern-Widgets hinzugefügt wurden. Er sagt auch, es nicht zu tun, tut nicht weh, sie entweder löschen.

(ich nicht getestet habe, aber ich denke, solange man sie explizit gelöscht werden, bevor die Mutter Widget gelöscht wird, dies in Ordnung sein sollte.)

In den meisten Fällen sollten Sie Widgets auf dem Stapel erstellen:

    QPushButton push("neu");

Auf diese Weise, sie gelöscht werden, wenn sie sich außerhalb des Geltungsbereichs werden. Wenn Sie wirklich auf dem Heap erstellt werden sollen, dann ist es in Ihrer Verantwortung auf sie zu nennen löschen, wenn sie nicht mehr benötigt werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top