Seite 1 von 1

Qdialog - Programm startet nicht

Verfasst: 15. Oktober 2009 10:03
von acdc
Hallo Leute,

Mein QT-Programm weist folgendes Problem auf:
Ich habe ein QMainWindow erstellt, einen Button in einer Leiste und starte damit einen QDialog mit ein paar Buttons und Labels. Das Programm hat bis zu dem Zeitpunkt wo ich die Sachen mit dem Layout (QHBoxLayout usw.) hinzugefügt habe funktioniert. Starte ich nun über den Button diesen Dialog und schließe und starten ich ihn daraufhin wieder so gibts einen falschen Speicherzugriff. Manchmal passiert das ganze auch gleich beim ersten Klick...
Das Layout habe ich mit dem QDesigner erstellt, die ui-datei in C++-Sourcecode verwandelt und in mein Programm eingebaut. Jetzt frage ich mich, was ich hier falsch mache.
Benutzte Vista mit SP1 und compiliere mit make. QT-Version ist 4.5.2.

So, ich hoffe ich habe keine wichtigen infos vergessen. Den Code und die compilierte Datei habe ich beigelegt.

Freue mich schon auf eure Antworten!
lg acdc

Verfasst: 15. Oktober 2009 11:18
von MiKla
Wie wäre es mit debuggen??? Ich verstehe das langsam nicht mehr, was das soll. Hast Du versucht den Fehler zu finden? Mit meinem Debugger habe ich den Fehler in 5 Minuten gefunden. D.h. ich weis, was bei Deinem Programm schief geht. Ich helfe wirklich gern aber nur man sieht das sich jemand bemüht.

Michael

Verfasst: 15. Oktober 2009 11:18
von arj
Ich würde anstatt

Code: Alles auswählen

SQLDialog *SQLVerbindungsdialog=new SQLDialog(this,"SQL-Dialog");
SQLVerbindungsdialog->exec();
ein

Code: Alles auswählen

SQLDialog SQLVerbindungsdialog=new SQLDialog(this,"SQL-Dialog");
SQLVerbindungsdialog.exec();
verwenden, dann wird der Dialog auch freigegeben wenn man ihn beendet.

Du gibst keines Deiner Objekte wieder frei, die Du anlegst! (Stichwort createButtons usw).

Zu Deinem Fehler: ich kann ihn (auch unter Linux) nachvollziehen. Er kommt daher, dass Du ein uninitialisiertes Objekt benutzt:

Im Konstruktor des SQLDialog steht:

Code: Alles auswählen

setTabs();
list = new QListWidget (horizontalLayoutWidget_2);
list->setObjectName(QString::fromUtf8("ListWidget"));
Du benutzt in

Code: Alles auswählen

setTabs()
aber schon list!

Tipp für das nächste mal: Einfach mal Codeteile auskommentieren bis der Fehler nicht mehr kommt und dann langsam einkommentieren. So kann man den Fehler schneller einkreisen.

Verfasst: 15. Oktober 2009 11:19
von arj
@Michael.Klank: Eigentlich hast Du recht :roll:

danke

Verfasst: 15. Oktober 2009 13:24
von acdc
...für die schnelle Antwort - es funktioniert jetzt auch einwandfrei.

Habe wahrscheinlich noch zu wenig Erfahrung. Auf das Freigeben der Objekte habe ich nicht geachtet. Werden die Buttons und andere Objekte nach dem schließwn des QDialog auch freigegeben?

Werde mich im Bezug auf Debugging schlau machen - Danke für die Hinweise!

acdc

Verfasst: 15. Oktober 2009 18:42
von arj
Wenn die Objekte mit new erstellt werden, werden sie nur freigegeben wenn Du sie von Hand wieder freigiebst (außer am Programmende, aber das ist SEHR SCHLECHTER Stil! :roll:)

Wenn Du sie NICHT mit new erstellst, also so:

Code: Alles auswählen

{
   QWidget widget;
}
Dann werden Sie freigegeben, wenn der Gültigkeitsbereich der Variablen verlassen wird. In diesem Falle also nach dem "}".

Wobei mich das jetzt selbst wundert, wenn man eine *.ui Datei hat, dann werden die irgendwie auch nicht freigegeben, wenn man sich den Code anschaut den der moc baut... Es könnte aber sein, dass ein QMainWindow / QDialog seine Kindelemente zerstört wenn es selbst zerstört wird?

Verfasst: 16. Oktober 2009 09:07
von AuE
@arj:
also soweit ih das immer verstanden hane werden QObjects dann freigegeben wenn der parent stirbt... Defactoo ist somit der Qt Mechanismus besser als der Garbage Collector.
Wenn man seinenWindow nun das delete_onClose mitgibt ist das kein Thema. Für seinen fall hast du sicher recht. wobei eig die meisten GUI elemente schon so lange wie das Programm leben sollten ;-)

Verfasst: 16. Oktober 2009 09:13
von MichaelS
arj hat geschrieben:Wenn die Objekte mit new erstellt werden, werden sie nur freigegeben wenn Du sie von Hand wieder freigiebst (außer am Programmende, aber das ist SEHR SCHLECHTER Stil! :roll:)

Wobei mich das jetzt selbst wundert, wenn man eine *.ui Datei hat, dann werden die irgendwie auch nicht freigegeben, wenn man sich den Code anschaut den der moc baut... Es könnte aber sein, dass ein QMainWindow / QDialog seine Kindelemente zerstört wenn es selbst zerstört wird?
Alle von QObject abgeleiteten Objekte zerstören ihre Kindobjekte, wenn sie selbst zerstört werden, siehe Qt-Doku:
When you create a QObject with another object as parent, the object will automatically add itself to the parent's children() list. The parent takes ownership of the object i.e. it will automatically delete its children in its destructor.
Das sollten eigentlich QT-Basics sein.

Gruß Michael

Verfasst: 16. Oktober 2009 09:25
von AuE
Aber wie gesagt.... hide != delete !!!
Wenns um was derb speicherkritisches geht. sonsten sollte hide einiges an performance bringen da der dialog "nur" vorgeholt werden muss!