Dynamisches TabWidget: Problem mit delete

Alles rund um die Programmierung mit Qt
Antworten
CKassiopaia
Beiträge: 38
Registriert: 21. April 2009 16:42

Dynamisches TabWidget: Problem mit delete

Beitrag von CKassiopaia »

Hallo zusammen!

ich möchte eine dynamisches TAB-Widget mit veränderbarer Anzahl an Tab-Seiten und QPushButton erzeugen. Dazu will ich zur Laufzeit eine Datei einlesen worin steht: 1. Wie viele Tabs ich benötige und 2. Wie viele Button auf jeder Tab-Seite sind.
Der Aufbau hat auch gut funktioniert:

Code: Alles auswählen

for(int i = 0; i  < X; i++){
        this->addTab(new QTabWidget, manager->getCanBuses().at(i).name);
        QGridLayout *layout = new QGridLayout(this->widget(i));
        QScrollArea *area = new QScrollArea(this->widget(i));
        QFrame *frame = new QFrame;

        for(int j = 0; j < Y; j++){
             QPushButton *button = new QPushButton("Test",  frame);
        }
}
Wie gesagt, das sieht soweit ganz gut aus...
Meine Frage bzw. Problem: Ich habe gelernt, dass ich für jedes "new" auch ein "delete" benötige. Stimmt das so schon einmal?
Nun wollte ich im Destruktor alles wieder löschen. Aber wie komme ich zu den einzelnen Objekten wieder hin?

Hatte mir dann testweise mal eine

Code: Alles auswählen

QList<QObject*> *objects =     objects = new QList<QObject*>;
erstellt und jedes neu erzeugte Element eingefügt. Im Destruktor dann entsprechend jedes Element gelöscht. Hat auch eigentlich funktioniert. Nur hin und wieder bricht das Programm beim Start oder beim beenden ab:

Code: Alles auswählen

*** glibc detected *** /Programmname: realloc(): invalid old size: 0x0000000000bc2c60 ***
======= Backtrace: =========
/lib/libc.so.6[0x7fd999cf09a8]
/lib/libc.so.6[0x7fd999cf45a1]
/lib/libc.so.6(realloc+0x12f)[0x7fd999cf501f]
...
Was sagt mir dass? (realloc() deutet ja auf ein Speicherproblem hin.... aber warum?)
Bzw. wo muss ich suchen?
Gibt es einen Eleganteren Weg für meine Aufgabe? Denn eigentlich muss ich später noch jeden Button abfragen und entsprechend mit einem Slot verbinden....dazu aber später.....

Vielen dank!
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Du solltest dich vielleicht ein wenig mehr mit der Qt API auseinandersetzen - da lernt man vieles. Unter anderem dass jedes Widgets mit childs diese bei der selbstlöschung automatisch mitlöscht ... du brauchst dich also um QObject derivate nicht kümmern SOLANGE sie geparented sind und das parent gelöscht wird ... deshalb sieht die main.cpp ja meist so aus:

Code: Alles auswählen

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w; // liegt auf dem stack, wird automatisch abgeräumt und räumt alle geparenteten childs mit ab
    w.show();
    return a.exec();
}
Im übrigen wird auch viel intern re-parented, zB wenn du es in ein Layout einfügst und dann das layout einem Widget zuweist werden alle gelayouteten Widgets an dieses reparented...

Gucksdu hier: http://doc.qt.nokia.com/4.6/qobject.html#details und klickste auf http://doc.qt.nokia.com/4.6/objecttrees.html lieste nochmer
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
CKassiopaia
Beiträge: 38
Registriert: 21. April 2009 16:42

Danke!

Beitrag von CKassiopaia »

Danke! Dann nimmt mir Qt ja mehr arbeit ab als ich dachte ;-)

Aber noch mal eine kurze Frage zum verständnis:
Wann ist ein Object eine Child? Und von Wem?
z.B.

Code: Alles auswählen

Class::Class(...){
    QFrame frame;
    QPushButton button(frame);
    ....
}
Für den Der button ist ja Child von frame und frame ist parent von button. Soweit habe ich das verstanden
Aber von dem ist frame child? Da ich nichts angegeben habe, wurde ja QWidget* parent = 0 verwendet? Wer ist dann Parent? In dem obigen Fall die Instanz der Klasse Object, die frame erzeugt hat? (Dazu hab ich in der Doku leider nicht viel finden können)
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Wenn man nix findet, denkt man nach, sucht, oder coded :) ich habs dir mal gecoded, das denken überlass ich dir ;)

Code: Alles auswählen

#include <QtGui>
#include <QtDebug>

// forward decl.
QString names(QObject *o);

// output for QWidgets
QString namesW(QWidget * w)
{
    QString msg;

    msg.append("Widget: ")
            .append(w->metaObject()->className())
            .append(" with name: ")
            .append(w->objectName());

    if (w->parent() != 0)
        msg     .append(" has parent: (")
                .append(names(w->parent()))
                .append(")");
    return "\t"+msg;
}

// output for QObjects, if they happen to be QWidgets the other one is called
QString names(QObject * o)
{
    // is QWidget? use the other one 
    if (o != 0 && qobject_cast<QWidget*>(o))
    {
        return namesW(qobject_cast<QWidget*>(o));
    }

    QString msg;

    msg.append("Object: ")
            .append(o->metaObject()->className())
            .append(" with name: ")
            .append(o->objectName());

    if (o->parent() != 0)
        msg     .append(" has parent: (")
                .append(names(o->parent()))
                .append(")");

    return "\t"+msg;
}




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

    QWidget w;  
    w.setObjectName("w");

    QVBoxLayout * lay = new QVBoxLayout;
    lay->setObjectName("Layout 1");

    QHBoxLayout * lay2 = new QHBoxLayout;
    lay2->setObjectName("Layout 2");

    QLabel * lab1 = new QLabel("1");
    lab1->setObjectName("1");

    QLabel * lab2 = new QLabel("2");
    lab2->setObjectName("2");

    QLabel * lab3 = new QLabel("3");
    lab3->setObjectName("3");


    qDebug() << "VOR Layout";
    qDebug() << names(&w);
    qDebug() << names(lay);
    qDebug() << names(lay2);
    qDebug() << names(lab1);
    qDebug() << names(lab2);
    qDebug() << names(lab3);

    w.setLayout(lay);
    lay->addWidget(lab1);
    lay->addWidget(lab2);
    qDebug() << "\n\n";
    qDebug() << "w.setLayout(lay); lay->addWidget(lab1); lay->addWidget(lab2);";
    qDebug() << names(&w);
    qDebug() << names(lay);
    qDebug() << names(lay2);
    qDebug() << names(lab1);
    qDebug() << names(lab2);
    qDebug() << names(lab3);


    lay2->addWidget(lab3);
    lay->addLayout(lay2);

    qDebug() << "\n\n";
    qDebug() << "lay2->addWidget(lab3); lay->addLayout(lay2);";
    qDebug() << names(&w);
    qDebug() << names(lay);
    qDebug() << names(lay2);
    qDebug() << names(lab1);
    qDebug() << names(lab2);
    qDebug() << names(lab3);
    w.show();

    return a.exec();
}
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
Antworten