fehler nach beenden

Alles rund um die Programmierung mit Qt
Antworten
uwe_road
Beiträge: 11
Registriert: 2. März 2011 12:20

fehler nach beenden

Beitrag von uwe_road »

hi, hab folgenden dialog geschriebe

Header

Code: Alles auswählen

#ifndef ADDFILESDIALOG_H
#define ADDFILESDIALOG_H

#include <QDialog>
#include <QTableWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QFileDialog>
#include <QTableWidgetItem>
#include <QStringList>



class addFilesDialog : public QDialog
{
    Q_OBJECT

public slots:
    void pressAddButton();

public:
    addFilesDialog();

private:
    QTableWidget *tableWidget;
    QPushButton *addButton;
    QPushButton *confirmButton;
    QPushButton *abortButton;



    void createButton();
    void setButtonSlots();
};

#endif // ADDFILESDIALOG_H

Cpp

Code: Alles auswählen


#include <addFilesDialog.h>

addFilesDialog::addFilesDialog()
{
    QHBoxLayout *hLayout = new QHBoxLayout(this);
    QVBoxLayout *vLayout = new QVBoxLayout;
    QWidget *widget = new QWidget;

    tableWidget = new QTableWidget(this);


    createButton();
    setButtonSlots();

    vLayout->addWidget(addButton);
    vLayout->addWidget(confirmButton);
    vLayout->addWidget (abortButton);


    vLayout->setAlignment(Qt::AlignTop);
    vLayout->addStretch();
    widget->setLayout(vLayout);

    hLayout->addWidget(tableWidget);
    hLayout->addWidget(widget);
}


//Trägt die über ein OpenDialog ausgewählten FIles in eine QTableWidget ein

void addFilesDialog::pressAddButton()
{

    int j = 0;
    QStringList list;
    QFileDialog *dialog = new QFileDialog;
    dialog->setViewMode(QFileDialog::Detail);
    dialog->setFileMode(QFileDialog::ExistingFiles);

    dialog->exec();
    list = dialog->selectedFiles();

    QStringList::Iterator i;
    tableWidget->setColumnCount(1);
    tableWidget->setRowCount(list.length());
    i = list.begin();

    while (!list.empty())
    {
         i = list.begin();
         QTableWidgetItem *item = new QTableWidgetItem(list.first());
         tableWidget->setItem(j,0,item);
         list.removeFirst();
         j++;
    }


}

//Inititalisiert Buttons

void addFilesDialog::createButton()
{
    addButton = new QPushButton(tr("Hinzufügen"),this);
    confirmButton = new QPushButton (tr("OK"),this);
    abortButton = new QPushButton (tr("Abbruch"),this);
}


//Weist den Buttons Slots zu
void addFilesDialog::setButtonSlots()
{
    connect(addButton,SIGNAL(clicked()),this,SLOT(pressAddButton()));
    connect(confirmButton,SIGNAL(clicked()),this,SLOT(close()));

}


funktioniert auch, nur sobald ich das fenster schließe sei es über den ok button oder über das x, bekomme ich die meldung ...exe funktioniert nicht mehr!
das problem tritt erst auf, wenn ich den abortButton einfüge, lasse ich ihn aus, wird das programm vernünftig beenden, kann mir den grund iwie nicht erklären!
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Der Debugger ist dein Freund...
QFileDialog *dialog erzeugt ein memleak, genauso das new QWidget in addFilesDialog()
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
uwe_road
Beiträge: 11
Registriert: 2. März 2011 12:20

Beitrag von uwe_road »

gut, und wie kann ich das jetzt beheben?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Indem man mit dem Debugger schaut wo genau es crasht ...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
uwe_road
Beiträge: 11
Registriert: 2. März 2011 12:20

Beitrag von uwe_road »

iwie hilft mir das nicht weiter....
hab das jetzt wie folgt gemacht, den debugger so laufen lassen, dann bleibt die FehlerMeldung von Windows, dass das Programm nicht mehr funktioniert nach dem ich es beendet habe aus!

dann habe ich haltepunkte gesetzt und dann noch ma geschaut, weiß aber gar nicht wodrauf ich achten muss, bin mit dem debugger nicht vertraut..

wäre nett, wenn jemand mal für mich schaun würde

hier nochmal der Quelltext


Header

Code: Alles auswählen

#ifndef ADDFILESDIALOG_H
#define ADDFILESDIALOG_H

#include <QDialog>
#include <QTableWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QFileDialog>
#include <QTableWidgetItem>
#include <QStringList>
#include <QLineEdit>



class addFilesDialog : public QDialog
{
    Q_OBJECT

public slots:
    void pressAddButton();

public:
    addFilesDialog();

private:
    QTableWidget *tableWidget;
    QPushButton *addButton;
    QPushButton *confirmButton;
    QPushButton *abortButton;
    QLineEdit *iE;
    QLineEdit *jE;


    void createButton();
    void setButtonSlots();

    QString fileName(QString s);
};

#endif // ADDFILESDIALOG_H
Cpp

Code: Alles auswählen

#include <addFilesDialog.h>

addFilesDialog::addFilesDialog()
{

    createButton();
    setButtonSlots();

    QHBoxLayout *hLayout = new QHBoxLayout(this);
    QVBoxLayout *vLayout = new QVBoxLayout;
    QWidget *widget = new QWidget;

    tableWidget = new QTableWidget(this);
    iE = new QLineEdit;
    jE = new QLineEdit;

    vLayout->addWidget(addButton);
    vLayout->addWidget(confirmButton);
    vLayout->addWidget (abortButton);
    vLayout->addWidget(iE);
    vLayout->addWidget(jE);


    vLayout->setAlignment(Qt::AlignTop);
    vLayout->addStretch();
    widget->setLayout(vLayout);

    hLayout->addWidget(tableWidget);
    hLayout->addWidget(widget);
}


//Trägt die über ein OpenDialog ausgewählten FIles in eine QTableWidget ein

void addFilesDialog::pressAddButton()
{

    int j = 0;
    QStringList list;
    QFileDialog *dialog = new QFileDialog(this);
    dialog->setViewMode(QFileDialog::Detail);
    dialog->setFileMode(QFileDialog::ExistingFiles);

    dialog->exec();
    list = dialog->selectedFiles();

    QStringList::Iterator i;
    tableWidget->setColumnCount(1);
    tableWidget->setRowCount(list.length());
    i = list.begin();

    while (!list.empty())
    {
         i = list.begin();
         QTableWidgetItem *item = new QTableWidgetItem(fileName(list.first()));
         tableWidget->setItem(j,0,item);
         list.removeFirst();
         j++;
    }


}

//Inititalisiert Buttons

void addFilesDialog::createButton()
{
    addButton = new QPushButton(tr("Hinzufügen"),this);
    confirmButton = new QPushButton (tr("OK"),this);
    abortButton = new QPushButton (tr("Abbruch"),this);
}


//Weist den Buttons Slots zu
void addFilesDialog::setButtonSlots()
{
    //connect(addButton,SIGNAL(clicked()),this,SLOT(pressAddButton()));
    connect(confirmButton,SIGNAL(clicked()),this,SLOT(close()));
    connect(abortButton,SIGNAL(clicked()),this,SLOT(close()));

}

QString addFilesDialog::fileName(QString s)
{
    QString f;
    int i = s.lastIndexOf('.');
    iE->setText(QString("%1").arg(i));
    f = s.left(i);
    int j = f.length()-f.lastIndexOf('/')-1;
    jE->setText(QString("%1").arg(j));
    f = f.right(j);

    return f;
}


vielen dank schon ma
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Der Debugger liefert dir be Crash doch einen Call-Stack, aus dem hervorgehen sollte, in welcher Funktion es kracht, außerdem was vorher alles aufgerufen wurde.

Und beim Beenden würde ich tippen, dass irgendwo ein Destruktor involviert ist, oder du in der main Mist baust.
Kannst du mal bitte dein komplettes Programm posten? Wenn es zu viel Code ist dann pack es in ein .zip und häng es hier im Forum (direkt hier drunter unter "Attachment"). Bitte alle Binaries und Qt-Libs weg lassen, nur den kompletten Source.
uwe_road
Beiträge: 11
Registriert: 2. März 2011 12:20

Beitrag von uwe_road »

das ist eigentlich soweit komplett, die klasse wird nacher eingebunden..
um nachzuschaun, einfach ne .h anlegen reinkopieren und das selbe mit der cpp datei und dann ne instanz in einer main klasse erstellen und mit show ausführen.
thx
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Funktioniert hier problemlos. Kannst du nicht noch deine main.cpp posten? Und du hast keine anderen Klassen am Start? Irgendwelche globalen Variablen?
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Hatte noch keinen Kaffee und kein Früstück und mir sträuben sich schon die Haare ;) Ton bitte nicht zu ernst nehmen:

Kritik:
Dir ist aber schon klar das wenn du 200 files nacheinander addest du 200 QFileDialogs erschaffst, die brav an dein Widget parentest und die erst beim Beenden wieder weg gemacht werden?

Warum benutzt du da ein BLACLASS * xc = new BLACLASS ... du brauchst den Filedialog doch nicht wieder. Also lass das rumgepointere und mach

Code: Alles auswählen

QFileDialog fd(parameter heir rein);
fd.exec();
dann wird der brav am Ende der Methode wieder freigegeben. Wenn du einen totaaaaaaaaal fiesen dicken selbstgestrickten Dialog hättest den du regelmässig wieder brauchst könntest du den auch über sowas(*) bauen:

Code: Alles auswählen

void irgndSonSlot() 
{ 
  static QDialog * d = 0;
  static QSpinBox * sp = 0;
  static QTextEdit  * te = 0;
  if (! d)
  {
      d = new QDialog(this);
      sp = new QSpinBox(this);
      te = new QTextEdit(this);
     // baue dialog hier zusammen
  }
  d.show(); 
  d.exec();
  // mach hier was mit den Inhalten von sp und te
  d.hide();
}
(*) aber nur wenn du weisst was hier GENAU passiert - in der Regel braucht man sowas eher nicht als static sondern macht sich den Dialog als member

Im Prinzip brauchst du den aber GARNICHT da QFileDialog eine Menge netter statischer MEthoden zu verfügung stellt die das alles in nem Einzeiler machen !! -> API
void addFilesDialog::pressAddButton()
{
// (0)
int j = 0;
QStringList list;
QFileDialog *dialog = new QFileDialog(this);
dialog->setViewMode(QFileDialog::Detail);
dialog->setFileMode(QFileDialog::ExistingFiles);

dialog->exec();

// (1)

list = dialog->selectedFiles();

QStringList::Iterator i;
tableWidget->setColumnCount(1);
tableWidget->setRowCount(list.length());
i = list.begin();

// (2)

while (!list.empty())
{
i = list.begin();
QTableWidgetItem *item = new QTableWidgetItem(fileName(list.first()));
tableWidget->setItem(j,0,item);
list.removeFirst(); // (!!!!!!!!! 3 !!!!!!!!!)
j++;
}


}
(0) gewöhn dir an, Variabeln so spät wie möglich zu deklarieren
(1) du kennst die statischen Members wie zB ::getExistingFileName() , ::getSaveName() :: getDirectory usw? --> API
(2) warum nicht:

Code: Alles auswählen

QStringList::Iterator i = list.begin(); 
while (i != list.end() ) { /* bla blubb */  ++i; }
(!!!!!!!!! 3 !!!!!!!!!) EVIL ... nimm ++i wenn du mit Iteratoren arbeiten willst und lass die Finger von der Liste - Listen zu modifizieren auf die man Iteratoren hat ist BÖSE ... wenn du sowas machen willst (also ohne iteratoren) nimm

Code: Alles auswählen

while (! list.empty())
{ // machwas mit liste.front();
  // entferne erstes element
}
(5) Die Trennung von Connects und der Buttonerschaffung ist ja nett - macht aber hier wenig Sinn. Wenn du das connect gleich in der selben Methode machst, sparst du dir Membervariabeln ein - ist ja nicht so als würdest du die irgendwann nochmal brauchen - ist aber Geschmackssache

(6) mach dich mit der API vertraut, dann brauchst du weniger selbst stricken:

Code: Alles auswählen

QString addFilesDialog::fileName(QString s)
{
    QString f;
    int i = s.lastIndexOf('.');
    iE->setText(QString("%1").arg(i));
    f = s.left(i);
    int j = f.length()-f.lastIndexOf('/')-1;
    jE->setText(QString("%1").arg(j));
    f = f.right(j);

    return f;
} 
-> QFileInfo, QString.section(), ... viele elegantere (und in 4 Monaten verständlichere) Wege dies zu tun,.
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

padreigh hat geschrieben:Listen zu modifizieren auf die man Iteratoren hat ist BÖSE ...
Diese Aussage ist mir zu allgemein. Bei QList ist das richtig:
Multiple iterators can be used on the same list. However, be aware that any non-const function call performed on the QList will render all existing iterators undefined. If you need to keep iterators over a long period of time, we recommend that you use QLinkedList rather than QList.
Alle Iteratoren werden ungültig gemacht, sobald man die Liste verändert.
Aber der letzte Satz sagt gleich, dass es auch anders geht - mit einer LinkedList. std::list ist so eine, oder eben QLinkedList. QList ist ein Zwischending von std::list und std::vector.
Antworten