Sporadische Programmabstürtze

Alles rund um die Programmierung mit Qt
Antworten
schoettner
Beiträge: 15
Registriert: 13. August 2012 17:12

Sporadische Programmabstürtze

Beitrag von schoettner »

Wiedermal hallo,

ich habe heute einen Suchdialog entwickelt, der bei mir leider unregelmäßig zu Programmabstürtzen führt. Wann der Fehler auftritt ist immer anders. Mal direkt beim Erstellen des Dialogs, mal erst beim Bestätigen. Ich nutze den Qt Creator um das Projekt zu bearbeiten. Nach einem Neustart des Rechners ist das Problem zeitweilen behoben.
Betriebsystem: Windows 7 Prof. 64bit
Qt Version: 4.8.2
Kompiler: MinGW 4.4.1
MySQL 5.5.27

Headerdatei:

Code: Alles auswählen

#ifndef SEARCHDIALOG_H
#define SEARCHDIALOG_H

#include <QDialog>
#include <QSqlDatabase>

class QLabel;
class QLineEdit;
class QPushButton;
class QListWidget;
class QComboBox;
class QCheckBox;
class QRadioButton;
class QListWidgetItem;
class QModelIndex;
class QString;

class SearchDialog : public QDialog
{
    Q_OBJECT

public:
    SearchDialog(QWidget *parent);
    QString get_statement();

private:
    QLabel* titlelabel;
    QLineEdit* titlelineEdit;
    QRadioButton* titleradioButton_1;
    QRadioButton* titleradioButton_2;
    QRadioButton* titleradioButton_3;
    QLabel* lengthlabel;
    QLineEdit* lengthlineEdit;
    QLabel* timedescriptionlabel;
    QRadioButton* lengthradioButton_1;
    QRadioButton* lengthradioButton_2;
    QLabel* ownerlabel;
    QComboBox* ownercomboBox;
    QCheckBox* ownercheckBox;
    QLabel* regielabel;
    QLineEdit* regielineEdit;
    QRadioButton* regieradioButton_1;
    QRadioButton* regieradioButton_2;
    QRadioButton* regieradioButton_3;
    QLabel* typelabel;
    QComboBox* typecomboBox;
    QCheckBox* typecheckBox;
    QLabel* lendedlabel;
    QRadioButton* lendedradioButton_yes;
    QRadioButton* lendedradioButton_no;
    QRadioButton* lendedradioButton_whatever;
    QLabel* genrelabel;
    QListWidget* genrelistWidget;
    QLabel* lingolabel;
    QListWidget* lingolistWidget;
    QPushButton* searchButton;
    QPushButton* cancelButton;

    std::vector <QString> id_person_list;
    std::vector <QString> id_type_list;
    std::vector <QString> id_genre_list;
    std::vector <QString> id_lingo_list;

    QSqlDatabase db;
    QString result_statement;

    void create_components();
    void create_Layout();
    void connect_componets();
    void load_data();

private slots:
    void create_where_statement();
};

#endif
Quelldatei

Code: Alles auswählen

#include <QtGui>
#include <QtSql>

#include "searchdialog.h"

SearchDialog::SearchDialog(QWidget *parent) : QDialog(parent)
{
    create_components();
    create_Layout();
    connect_componets();
    db = QSqlDatabase::database();
    load_data();
}

void SearchDialog::create_components()
{
    titlelabel = new QLabel(tr("&Titel"));
    timedescriptionlabel = new QLabel(tr("in Minuten"));
    titlelineEdit = new QLineEdit;
    titlelabel->setBuddy(titlelineEdit);
    titleradioButton_1 = new QRadioButton(tr("Im Titel enthalten"));
    titleradioButton_1->setChecked(true);
    titleradioButton_2 = new QRadioButton(tr("Titelanfang"));
    titleradioButton_2->setChecked(false);
    titleradioButton_3 = new QRadioButton(tr("Genauer Wortlaut"));
    titleradioButton_3->setChecked(false);

    lengthlabel = new QLabel(tr("&Länge"));
    lengthlineEdit = new QLineEdit;
    QRegExp regExp_duration("[1-9][0-9]{0,2}");
    lengthlineEdit->setValidator(new QRegExpValidator(regExp_duration,this));
    lengthlabel->setBuddy(lengthlineEdit);
    lengthradioButton_1 = new QRadioButton(tr("<="));
    lengthradioButton_1->setChecked(true);
    lengthradioButton_2 = new QRadioButton(tr(">="));
    lengthradioButton_2->setChecked(false);

    ownerlabel = new QLabel(tr("Besitzer"));
    ownercomboBox = new QComboBox;
    ownercheckBox = new QCheckBox(tr("Egal"));
    ownercheckBox->setChecked(true);

    regielabel = new QLabel(tr("&Regie"));
    regielineEdit = new QLineEdit;
    regielabel->setBuddy(regielineEdit);
    regieradioButton_1 = new QRadioButton(tr("In Regie enthalten"));
    regieradioButton_1->setChecked(true);
    regieradioButton_2 = new QRadioButton(tr("Regieanfang"));
    regieradioButton_2->setChecked(false);
    regieradioButton_3 = new QRadioButton(tr("Genauer Wortlaut"));
    regieradioButton_3->setChecked(false);

    typelabel = new QLabel(tr("&Typ"));
    typecomboBox = new QComboBox;
    typelabel->setBuddy(typecomboBox);
    typecheckBox = new QCheckBox(tr("Egal"));
    typecheckBox->setChecked(true);

    lendedlabel = new QLabel(tr("Verliehen"));
    lendedradioButton_yes = new QRadioButton(tr("Ja"));
    lendedradioButton_yes->setChecked(false);
    lendedradioButton_no = new QRadioButton(tr("Nein"));
    lendedradioButton_no->setChecked(false);
    lendedradioButton_whatever = new QRadioButton(tr("Egal"));
    lendedradioButton_whatever->setChecked(true);

    genrelabel = new QLabel(tr("&Genre"));
    genrelistWidget = new QListWidget;
    genrelabel->setBuddy(genrelistWidget);

    lingolabel = new QLabel(tr("&Sprache"));
    lingolistWidget = new QListWidget;
    lingolabel->setBuddy(lingolistWidget);

    searchButton = new QPushButton(tr("Suchen"));
    searchButton->setDefault(true);
    cancelButton = new QPushButton(tr("&Abbrechen"));
    cancelButton->setDefault(false);
}

void SearchDialog::create_Layout()
{
    QButtonGroup* titlegroup = new QButtonGroup;
    titlegroup->addButton(titleradioButton_1);
    titlegroup->addButton(titleradioButton_2);
    titlegroup->addButton(titleradioButton_3);

    QVBoxLayout* titleLayout = new QVBoxLayout;
    titleLayout->addWidget(titlelabel);
    titleLayout->addWidget(titlelineEdit);
    titleLayout->addWidget(titleradioButton_1);
    titleLayout->addWidget(titleradioButton_2);
    titleLayout->addWidget(titleradioButton_3);

    QButtonGroup* lengthgroup = new QButtonGroup;
    lengthgroup->addButton(lengthradioButton_1);
    lengthgroup->addButton(lengthradioButton_2);

    QVBoxLayout* lengthLayout = new QVBoxLayout;
    lengthLayout->addWidget(lengthlabel);
    lengthLayout->addWidget(lengthlineEdit);
    lengthLayout->addWidget(lengthradioButton_1);
    lengthLayout->addWidget(lengthradioButton_2);
    lengthLayout->addStretch();

    QVBoxLayout* ownerLayout = new QVBoxLayout;
    ownerLayout->addWidget(ownerlabel);
    ownerLayout->addWidget(ownercomboBox);
    ownerLayout->addWidget(ownercheckBox);
    ownerLayout->addStretch();

    QHBoxLayout* topLayout = new QHBoxLayout;
    topLayout->addLayout(titleLayout);
    topLayout->addLayout(lengthLayout);
    topLayout->addLayout(ownerLayout);

    QButtonGroup* regiegroup = new QButtonGroup;
    regiegroup->addButton(regieradioButton_1);
    regiegroup->addButton(regieradioButton_2);
    regiegroup->addButton(regieradioButton_3);

    QVBoxLayout* regieLayout = new QVBoxLayout;
    regieLayout->addWidget(regielabel);
    regieLayout->addWidget(regielineEdit);
    regieLayout->addWidget(regieradioButton_1);
    regieLayout->addWidget(regieradioButton_2);
    regieLayout->addWidget(regieradioButton_3);

    QVBoxLayout* typeLayout = new QVBoxLayout;
    typeLayout->addWidget(typelabel);
    typeLayout->addWidget(typecomboBox);
    typeLayout->addWidget(typecheckBox);
    typeLayout->addStretch();

    QButtonGroup* lendedgroup = new QButtonGroup;
    lendedgroup->addButton(lendedradioButton_yes);
    lendedgroup->addButton(lendedradioButton_no);
    lendedgroup->addButton(lendedradioButton_whatever);

    QVBoxLayout* lendedLayout = new QVBoxLayout;
    lendedLayout->addWidget(lendedlabel);
    lendedLayout->addWidget(lendedradioButton_yes);
    lendedLayout->addWidget(lendedradioButton_no);
    lendedLayout->addWidget(lendedradioButton_whatever);
    lendedLayout->addStretch();

    QHBoxLayout* midLayout = new QHBoxLayout;
    midLayout->addLayout(regieLayout);
    midLayout->addLayout(typeLayout);
    midLayout->addLayout(lendedLayout);

    QVBoxLayout* genreLayout = new QVBoxLayout;
    genreLayout->addWidget(genrelabel);
    genreLayout->addWidget(genrelistWidget);

    QVBoxLayout* lingoLayout = new QVBoxLayout;
    lingoLayout->addWidget(lingolabel);
    lingoLayout->addWidget(lingolistWidget);

    QHBoxLayout* bottomLayout = new QHBoxLayout;
    bottomLayout->addLayout(genreLayout);
    bottomLayout->addLayout(lingoLayout);

    QHBoxLayout* buttonLayout = new QHBoxLayout;
    buttonLayout->addStretch();
    buttonLayout->addWidget(searchButton);
    buttonLayout->addWidget(cancelButton);
    buttonLayout->addStretch();

    QVBoxLayout* mainLayout = new QVBoxLayout;
    mainLayout->addLayout(topLayout);
    mainLayout->addLayout(midLayout);
    mainLayout->addLayout(bottomLayout);
    mainLayout->addLayout(buttonLayout);

    setLayout(mainLayout);
    setWindowTitle(tr("Suchen"));
    setFixedHeight(sizeHint().height());
    setFixedWidth(sizeHint().width());
}

void SearchDialog::connect_componets()
{
    connect(searchButton,SIGNAL(clicked()),this,SLOT(create_where_statement()));
    connect(cancelButton,SIGNAL(clicked()),this,SLOT(reject()));
}

void SearchDialog::load_data()
{
    if (db.open())
    {
        QString statement;
        QSqlQuery query;

        //####################################### load all persons #######################################
        statement  =    "SELECT id,firstname,secondname "
                        "FROM person";

        query.exec(statement);
        while (query.next())
        {
            id_person_list.push_back(query.value(0).toString());
            ownercomboBox->addItem(query.value(1).toString() + " " + query.value(2).toString());
        }
        query.clear();

        //####################################### load all typs #######################################
        statement  =    "SELECT id,description "
                        "FROM typ";
        query.exec(statement);
        while (query.next())
        {
            id_type_list.push_back(query.value(0).toString());
            typecomboBox->addItem(query.value(1).toString());
        }
        query.clear();

        //####################################### load all genres #######################################
        statement = "SELECT description,id "
                    "FROM genre;";
        query.exec(statement);
        while (query.next())
        {
            QListWidgetItem* item = new QListWidgetItem;
            item->setText(query.value(0).toString());
            item->setCheckState(Qt::Unchecked);
            genrelistWidget->addItem(item);
            id_genre_list.push_back(query.value(1).toString());
        }
        query.clear();

        //####################################### load all languages #######################################
        statement = "SELECT language,id "
                    "FROM language;";
        query.exec(statement);
        while (query.next())
        {
            QListWidgetItem* item = new QListWidgetItem;
            item->setText(query.value(0).toString());
            item->setCheckState(Qt::Unchecked);
            lingolistWidget->addItem(item);
            id_lingo_list.push_back(query.value(1).toString());
        }
        query.clear();

    }
    else //if the db could not be opend
    {
        QMessageBox::critical(0, QObject::tr("Connection Error"),db.lastError().text());
    }
}

void SearchDialog::create_where_statement()
{
    QString statement;
    bool last_is_AND = true;
    //##################################### check title #####################################
    if (titlelineEdit->text()!="")
    {
        statement = "m.titel LIKE '";
        if(titleradioButton_1->isChecked())
        {
            statement += "%" + titlelineEdit->text() + "%' ";
        }
        else
        {
            if (titleradioButton_2->isChecked())
            {
                statement += titlelineEdit->text() + "%' ";
            }
            else
            {
                statement +=titlelineEdit->text() + "' ";
            }
        }
        last_is_AND = false;
    }

    //##################################### check regie #####################################
    if (regielineEdit->text()!="")
    {
        if (!last_is_AND)
        {
            statement += "AND ";
        }
        statement += "m.regie LIKE '";
        if (regieradioButton_1->isChecked())
        {
            statement += "%" + regielineEdit->text() + "%' ";
        }
        else
        {
            if (regieradioButton_2->isChecked())
            {
                statement += regielineEdit->text() + "%' ";
            }
            else
            {
                statement += regielineEdit->text() + "' ";
            }
        }
        last_is_AND = false;
    }

    //##################################### check duration #####################################
    if (lengthlineEdit->text()!="")
    {
        if (!last_is_AND)
        {
            statement += "AND ";
        }
        statement += "m.duration ";
        if (lengthradioButton_1->isChecked())
        {
            statement += "<=" + lengthlineEdit->text() + " ";
        }
        else
        {
            statement += ">=" + lengthlineEdit->text() + " ";
        }
        last_is_AND = false;
    }

    //##################################### check owner #####################################
    if (!ownercheckBox->isChecked())
    {
        if (!last_is_AND)
        {
            statement += "AND ";
        }
        statement += "p.id = " + id_person_list.at(ownercomboBox->currentIndex())+ " ";
        last_is_AND = false;
    }

    //##################################### check type #####################################
    if (!typecheckBox->isChecked())
    {
        if (!last_is_AND)
        {
            statement += "AND ";
        }
        statement += "t.id = " + id_type_list.at(typecomboBox->currentIndex()) + " ";

    }

    //##################################### check lended #####################################
    if (!lendedradioButton_whatever->isChecked())
    {
        if (!last_is_AND)
        {
            statement += "AND ";
        }
        if (lendedradioButton_yes->isChecked())
        {
            statement += "m.lended=1 ";
        }
        else
        {
            statement += "m.lended=0 ";
        }
        last_is_AND = false;
    }

    //##################################### check genre #####################################
    QString genre_String;
    for(unsigned int i=0; i<id_genre_list.size(); i++)
    {
         if (genrelistWidget->item(i)->checkState()==Qt::Checked)
         {
             if (genre_String.isEmpty())
             {
                 genre_String = id_genre_list.at(i);//genrelistWidget->currentIndex().row());
             }
             else
             {
                 genre_String += ", " + id_genre_list.at(i);//genrelistWidget->currentIndex().row());
             }
         }
     }
    if (!genre_String.isEmpty())
    {
        if (!last_is_AND)
        {
            statement += "AND ";
        }
        statement += "mg.genre_id IN (" + genre_String + ") ";
        last_is_AND = false;
    }

     //##################################### check language #####################################
     QString lingo_String;
     for(unsigned int i=0; i<id_lingo_list.size(); i++)
     {
          if (lingolistWidget->item(i)->checkState()==Qt::Checked)
          {
              if (lingo_String.isEmpty())
              {
                  lingo_String = id_lingo_list.at(i);//lingolistWidget->currentIndex().row());
              }
              else
              {
                  lingo_String += ", " + id_lingo_list.at(i);//lingolistWidget->currentIndex().row());
              }
          }
      }
     if (!lingo_String.isEmpty())
     {
         if (!last_is_AND)
         {
             statement += "AND ";
         }
         statement += "ml.language_id IN (" + lingo_String + ") ";
         last_is_AND = false;
     }

    //##################################### finish statement #####################################
    if (!statement.isEmpty())
    {
    statement +=";";
    result_statement=statement;
    //QMessageBox::information(0,"statement",statement);
    accept();
    }
}

QString SearchDialog::get_statement()
{
    return result_statement;
}
Aufruf

Code: Alles auswählen

void MainWindow::search()
{
    searchDialog = new SearchDialog(this);
    if (searchDialog->exec())
    {
        ui->unfilteredButton->setDisabled(false);
        update_table(searchDialog->get_statement()); //hier wird die generierte where bedingung an meine ladefunktion übergeben
        filter=true;
        disable_buttons();
    }
    delete searchDialog;
}
Wenn das Programm nicht abstürtzt, funktioniert der Code einwandfrei. (Naja das mit Genre und Sprache über IN laden ist noch nicht, was ich eigentlich will. Eigentlich sollen nur Filme geladen werden, die alle Kriterien erfüllen und nicht wie über IN eine OR Veknüfung. Aber ich denke über SQL Statements lässt sich das Problem leider nicht lösen. Ist aber eine andere Baustelle ;) ).
Nach einigen malen Kompilieren fangen die Abstürtze dann an und tretten ab dann eigendlich jedes mal auf, wenn der Dialog verwendet werden soll.
omegano
Beiträge: 21
Registriert: 18. Mai 2012 18:32

Re: Sporadische Programmabstürtze

Beitrag von omegano »

also ich bei mir hing es damals bei nem ähnlichen fehler mit dem delete zusammen.

Probier es einfach mal ohne den delete und guck mal ob es immernoch passiert. bei mir hing es damals zusammen das er versucht hat zu deleten obwohl irgendwas ich glaube n thread wars(ist aber auch egal), noch versucht hat mit dem dialog zu arbeiten.
brax
Beiträge: 208
Registriert: 11. Mai 2010 11:22

Re: Sporadische Programmabstürtze

Beitrag von brax »

Grundsätzlich ist es immer komisch, ein Objekt per "new" anzulegen, das in derselben Methode wieder deleted wird. Es gibt auch keinen Grund (jedenfalls nicht im geposteten Code), dass searchDialog ein Member vom MainWindow sein muss. Die search Methode könnte genauso gut so aussehen:

Code: Alles auswählen

void MainWindow::search()
{
    SearchDialog searchDialog;
    if (searchDialog.exec())
    {
        ui->unfilteredButton->setDisabled(false);
        update_table(searchDialog.get_statement()); //hier wird die generierte where bedingung an meine ladefunktion übergeben
        filter=true;
        disable_buttons();
    }
}
Dann brauchst Du Dir über das delete keine Gedanken zu machen.

Was den Absturz angeht solltest Du ganz dringend mal einen Debugger benutzen! Der sagt Dir im Moment des Absturzes ganz genau in welcher Zeile Dein Programm verreckt und dann kommst Du ziemlich sicher von ganz alleine auf die Lösung. Einfach im QtCreator auf den grünen Button mit dem Käfer clicken und fertig.
Antworten