[SOLVED] [Qt::WidgetAttribute] Qt::WA_DeleteOnClose crashing the program



  • Hello Qt Devs!

    I have a MainWindow which instantiates a subclassed MainWindow, called DataEntryWindow. This DataEntryWindow is instantiated with some arguments that come from the MainWindow.

    So, each time I close the DataEntryWindow, I want the instance to be deleted. However, each time I use:

    @ dataentrywindow.setAttribute(Qt::WA_DeleteOnClose, true); @

    the program crashes each time I call close. Any idea why that wouldl happen? Do you need any code, or it this a general situation?

    Thanks!



  • a compilable, as small as possible example would be good.



  • Here are the two source files, stripped of any extra data. Can't can compilable, as it is connected to a DB and pretty much everything depends on the DB.

    I tried messing with the destructor, didn't change anything. I'm thinking of creating a slot that deletes the _instance and sets it to 0 instead of using the aforementioned attributed.

    EDIT: The slot idea doesn't work.
    Thanks!

    @MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    initializationPointers();
    populateInterfaceBoxes();
    connectDialogs();
    prepareLayout();
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::populateTestData(int entretien)
    {
    for (int j = 0; j < TestCreator::accessTestVector()->size(); ++j)
    {
    TestCreator::accessTestVector()->value(j)->close();
    }

    int offset = entModel->data(entModel->index(entretien, entModel->fieldIndex("IndexEntretien")), Qt::DisplayRole).toInt();
    qDebug() << "Entretien:" << offset;
    
    if (groupQuery == 0)
    {
        groupQuery = new QSqlQuery(QSqlDatabase::database("qaimagerie"));
        groupQuery->prepare("SELECT DISTINCT \"IndexGroupe\", \"GR_Nom\" FROM \"**************\" WHERE \"IndexEntretien\" = :entretien");
    }
    
    if (catQuery == 0)
    {
        catQuery = new QSqlQuery(QSqlDatabase::database("qaimagerie"));
        catQuery->prepare("SELECT DISTINCT \"IndexCategorie\", \"CAT_Nom\" FROM \"******************\" WHERE \"IndexEntretien\" = :entretien AND \"IndexGroupe\" = :group");
    }
    
    if (testQuery == 0)
    {
        testQuery = new QSqlQuery(QSqlDatabase::database("qaimagerie"));
        testQuery->prepare("SELECT \"IndexTest\", \"TES_Description\", test FROM \"******************\" WHERE \"IndexEntretien\" = :entretien AND \"IndexGroupe\" = :group AND \"IndexCategorie\" = :categorie" );
    }
    
    if (treeModel == 0)
    {
        treeModel = new QStandardItemModel(this);
    }
    
    treeModel->clear();
    
    QStringList headers;
    headers << "Tests";
    treeModel->setHorizontalHeaderLabels(headers);
    
    groupQuery->bindValue(":entretien", offset);
    groupQuery->exec&#40;&#41;;
    
    if (!groupQuery->size(&#41;&#41;
        qDebug() << "Size of group query is null!";
    
    for (int i =0; i<groupQuery->size(); ++i)
    {
        groupQuery->next();
        groupItem = new QStandardItem(groupQuery->value(1).toString());
    
        catQuery->bindValue(":entretien", offset);
        catQuery->bindValue(":group", groupQuery->value(0).toInt());
        catQuery->exec&#40;&#41;;
    
        if (!catQuery->size(&#41;&#41;
            qDebug() << "Size of catQuery is null!";
    
        for (int j=0; j<catQuery->size(); ++j)
        {
            catQuery->next();
            catItem = new QStandardItem(catQuery->value(1).toString());
            testQuery->bindValue("entretien", offset);
            testQuery->bindValue(":group", groupQuery->value(0).toInt());
            testQuery->bindValue(":categorie", catQuery->value(0).toInt());
            testQuery->exec&#40;&#41;;
    
            if (!testQuery->size(&#41;&#41;
                qDebug() << "Size of testQuery is null!";
    
            for (int k=0; k<testQuery->size(); ++k)
            {
                testQuery->next();
                qDebug() << testQuery->value(0).toInt();
                testItem = new QStandardItem(testQuery->value(2).toString());
                testItem->setToolTip(testQuery->value(1).toString());
    
                TestCreator::Instance(this)->instantiateGroups(groupQuery->value(0).toInt(),
                                                               catQuery->value(0).toInt(),
                                                               testQuery->value(0).toInt());
    
                if (TestCreator::accessTestVector()->size()>0)
                {
                    for (int h = 0; h < TestCreator::accessTestVector()->size(); ++h)
                    {
                        populateStackedWidget(h);
                    }
                }
    
                catItem->appendRow(testItem);
            }
            groupItem->appendRow(catItem);
        }
        treeModel->appendRow(groupItem);
    }
    this->populateListView(treeModel);
    

    }

    // Must be reimplemented in subclasses
    void MainWindow::populateListView(QStandardItemModel *model)
    {
    ui->MW_testTreeView->setModel(model);
    }

    void MainWindow::populateStackedWidget(int value)
    {
    stackedWidget->addWidget(TestCreator::accessTestVector()->value(value));
    }

    void MainWindow::instantiateDEW()
    {
    int entretien = newQAInstanceDia->accessEntretien();
    qDebug() << "Ent: " << entretien;

    int appareil = newQAInstanceDia->accessAppareil();
    qDebug() << "App: " << appareil;
    
    int employee = newQAInstanceDia->accessEmployee();
    qDebug() << "Emp: " << employee;
    
    DataEntryWindow::Instance(this, entretien, appareil, employee)->show();
    

    }@

    @#include "dataentrywindow.h"

    DataEntryWindow *DataEntryWindow::_instance = 0;

    DataEntryWindow *DataEntryWindow::Instance(QWidget *parent, int entretien, int appareil, int employee)
    {
    if (_instance == 0)
    {
    _instance = new DataEntryWindow(parent, entretien, appareil, employee);
    }
    return _instance;
    }

    DataEntryWindow::DataEntryWindow(QWidget *parent, int entretien, int appareil, int employee ) :
    MainWindow(parent)
    {
    setupUi(this);

    prepareLayout();
    initializationPointers();
    populateTestData(entretien);
    appID = appareil;
    empID = employee;
    

    }

    DataEntryWindow::~DataEntryWindow()
    {
    delete _instance;
    _instance = 0;
    }

    void DataEntryWindow::populateListView(QStandardItemModel *model)
    {
    DEW_testTreeView->setModel(model);
    }

    void DataEntryWindow::populateStackedWidget(int value)
    {
    stackedWidget->addWidget(TestCreator::accessTestVector()->value(value));

    }

    void DataEntryWindow::prepareLayout()
    {
    stackedWidget = new QStackedWidget(this);
    horizontalLayout_2->addWidget(stackedWidget);
    }
    @



  • try something like this ...
    @
    DataEntryWindow::~DataEntryWindow()
    {
    _instance->deleteLater();
    }
    @
    and make some slot connected to QObject::destroyed() signal. In this slot set _instance = NULL;



  • [quote author="Joey Dumont" date="1311089668"]
    @ dataentrywindow.setAttribute(Qt::WA_DeleteOnClose, true); @
    [/quote]

    This looks like something that is created on stack. It will be deleted when the variable goes out of scope. You don't need to set delete on close on it. If you need it, create the data entry window differently:

    @DataEntryWindow *dew = new DataEntryWindow(this);
    dew->setAttribute(Qt::WA_DeleteOnClose, true);@

    That should do it.



  • Thanks guys, it worked!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.