Widget schließt ganzes Programm und nicht nur sich selbst

Alles rund um die Programmierung mit Qt
Antworten
Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Widget schließt ganzes Programm und nicht nur sich selbst

Beitrag von Meho »

Hallo Ihr Lieben,
ich muss euch nochmal um Hilfe bitten.

Ich habe eine Widget erstellt wo ich dem Nutzer Grundeinstellungen zum Programm eintragen lasse, wenn er diese noch nicht hat.

Wenn im Fenster der OK Button betätigt wird, verarbeite ich die Eingabe und sage,

Code: Alles auswählen

this->clode();
um das Fenster zu schließen, aber es schließt sich das Ganze Programm. Wieso?

Ich vermute das liegt an meiner Deklaration des Widgets weil ich es auf dem Heap erzeuge oder?

Code: Alles auswählen

db_setting *datenbankEinstellungen = new db_setting();
         datenbankEinstellungen->show();
Wieso kann ich eigentlich manchmal sachen OBJECT.show() OBJECTPOINTER->show() aber nicht .exec oder ->exec.
in diesem Beispiel get das nicht.(falsch geerbt?)

Ich bräuchte mal ein HowTo/Tutorial das mir eine Art Leitfaden für die Erstellung einer Gesammtanwendung gibt.
Also was sollte in die Main() wie realisiere ich MVC-Muster am besten in QT. Man findet jede Menge Anleitungen, wo die Einzelelemente (Slots, Signale, Designer,Widget, ...) beschrieben sind, aber nicht ihr Zusammenspiel. kennt jemand eine gute Anleitung, gerne auch in Englisch?

Danke schonmal für eine Hilfe !
hilefoks
Beiträge: 144
Registriert: 13. März 2008 16:09

Re: Widget schließt ganzes Programm und nicht nur sich selbs

Beitrag von hilefoks »

Moin,

um deine Frage zu beantworten, müsste ich mehr Code sehen. In welcher Klasse ist z.B. das this->close()?
Meho hat geschrieben:Ich vermute das liegt an meiner Deklaration des Widgets weil ich es auf dem Heap erzeuge oder?
Nein, das ist nicht das Problem.
Meho hat geschrieben:Wieso kann ich eigentlich manchmal sachen OBJECT.show() OBJECTPOINTER->show() aber nicht .exec oder ->exec.
in diesem Beispiel get das nicht.(falsch geerbt?)
Falsch geerbt kann man so nicht direkt sagen. Aber ja, nicht alle Klassen haben eine exec() Methode. QWidget besitzt zunächst einmal nur die show() Methode. Nur die Dialog-Klassen (QDialog, QFileDialog, QMessageBox, ...) haben auch eine exec() Methode.

In deinem Fall könnte es sinnvoll sein, das dein Dialog für die Einstellungen von QDialog ableitet statt von QWidget.
Meho hat geschrieben:Ich bräuchte mal ein HowTo/Tutorial das mir eine Art Leitfaden für die Erstellung einer Gesammtanwendung gibt.
Das gibt es so leider nicht. Zumindest nicht für wirklich umfangreiche Anwendungen. Aber die Qt Dokumentation und die Beispiele sind ja durchaus ganz lehrreich - z.B. http://qt-project.org/doc/qt-5.0/qtwidg ... ation.html

Wenn du das Design größerer Anwendungen lernen möchtest, dann führt wohl kein Weg daran vorbei, den Code solcher Anwendungen zu lesen. Vielleicht kennst du ja ein Qt basiertes Programm das dich interessiert (VLC, PSI, KDE, ...). Schau in die Bugtracker und hilf einfache Bugs zu beheben... so lernst du meiner Meinung nach am besten. So oder so - du wirst dir Zeit nehmen müssen.
Meho hat geschrieben:Also was sollte in die Main() wie realisiere ich MVC-Muster am besten in QT. Man findet jede Menge Anleitungen, wo die Einzelelemente (Slots, Signale, Designer,Widget, ...) beschrieben sind, aber nicht ihr Zusammenspiel. kennt jemand eine gute Anleitung, gerne auch in Englisch?
Das MVC-Muster wird in Qt, bzw. bei QWidget basierten Anwendungen, meiner Meinung nach nicht wirklich verwendet. Unabhängig davon - mach dir darüber erstmal nicht so viele Gedanken. Die beste Dokumentation die du finden kannst ist Quellcode von Open Source Projekten. Bei KDE findest du sehr viel davon, z.B. Amarok oder Marble. Aber auch PSI ist durchaus lehrreich.

Als Dokumentation kann ich eigentlich, neben der Qt Doku selbst, noch das KDE Techbase empfehlen. Natürlich ist sehr viel der Dokumentation sehr KDE spezifisch.
Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Re: Widget schließt ganzes Programm und nicht nur sich selbs

Beitrag von Meho »

Hallo hilefoks,
vielen Dank für deine umfangreiche Antwort.
Sie beruhigt mich, denn ich dachte schon ich bin zu blöd für QT und C++ :-/
hilefoks hat geschrieben: In deinem Fall könnte es sinnvoll sein, das dein Dialog für die Einstellungen von QDialog ableitet statt von QWidget.
Ja das habe ich auch gerade recherchiert QDialog ermöglicht es auch das aufrufende Programm warten zu lassen, das ist auch noch ein Problem an dem ich hänge, aber da half googel schon weiter ;-)

hilefoks hat geschrieben:um deine Frage zu beantworten, müsste ich mehr Code sehen. In welcher Klasse ist z.B. das this->close()?
In dem Widget was ich erzeuge, daher wundert es mich auch, das "this" mehr anspricht auser das Objekt der Klasse :-(.
Ich möchte hier nicht so viel Code posten weil der auf jede menge Klassen verteilt ist und daher die Sache sehr unübersichtlich ist. Eure Antworten sind auch so schon sehr hilfreich.

Ich versuch das jetzt mal mit QDialog und berichte über Erfolg oder Misserfolg.

Vielen Dank!
Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Re: Widget schließt ganzes Programm und nicht nur sich selbs

Beitrag von Meho »

So,
ich bin weiter :-)
Unter folgendem Link findet man gute Dialog Beispiele von QT mit Quellcode in den kompletten Dateien.
http://qt-project.org/doc/qt-5.0/qtwidg ... alogs.html

Leider erben in den meisten Beispielen die selbstgeschribenen Dialoge von QWidget, außer das hier:
http://qt-project.org/doc/qt-5.0/qtwidg ... nsion.html

Nun erstelle ich mit folgemdem Code mein Dialog(db_setting) in meiner main.cpp

Code: Alles auswählen

db_setting datenbankEinstellungen;
        datenbankEinstellungen.setModal(true);
        datenbankEinstellungen.exec();
Wobei das "datenbankEinstellungen.setModal(true);" bewirkt, dass die Codeausführung solange angehalten wird bis der Dialog beendet wurde.

Was ich noch nicht verstehe ist, das es zwar eine funktion .show(); gibt diese aber bei mir nichts anzeigt, also nicht funktioniert, ich muss also .excex(); nehmen.
_________________________________________________________

Mein eigentliches Problem habe ich auch gefunden:

Fehler1:
Ich hatte vergessen, dass ich den Slot close() mit qApp->quit; überlagert hatte, :-( wie dumm ....

Fehler2:
Ein falsch programmierter Pointer, den ich nun nicht mehr brauche hat das Programm zum abstürzen gebracht.

vielen Dank für die Hilfe!
Gruß Meho
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Widget schließt ganzes Programm und nicht nur sich selbs

Beitrag von Christian81 »

Wenn man exec() benutzt ist setModal() unnötig. Siehe auch https://qt-project.org/doc/qt-4.8/qdialog.html#exec

und show() funktioniert auch, nur da Du den Dialog mal wieder auf den Stack anlegst ist er wie deine MessageBox gleich wieder weg sobald die Funktion beendet wird -> C++ Grundlagen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Re: Widget schließt ganzes Programm und nicht nur sich selbs

Beitrag von Meho »

Christian81 hat geschrieben: und show() funktioniert auch, nur da Du den Dialog mal wieder auf den Stack anlegst ist er wie deine MessageBox gleich wieder weg sobald die Funktion beendet wird -> C++ Grundlagen.
Aber genau deswegen leg ich das ja auf dem Stack und nicht auf den Heap ich möchte ja keine Datenmüllschleuder programmieren ;-).
Ich dachte wenn ich .setModal(true); setze wartet das Hauptprogramm und da dürfte die Funktion ja nicht weiterlaufen und es sich auch nicht beenden, so die Aussage in einem Forum.
(Man soll eben nicht alles glauben was im Internet steht ;-))

In der Doku steht folgendes:
"A modal dialog is a dialog that blocks input to other visible windows in the same application."[...]
"When an application modal dialog is opened, the user must finish interacting with the dialog and close it before they can access any other window in the application."

Es steht geschrieben:
"The most common way to display a modal dialog is to call its exec() function."[...]
"An alternative is to call setModal(true) or setWindowModality(), then show(). Unlike exec(), show() returns control to the caller immediately."

Also.. *.exec ist eine Alternative zu setModal(true) + *.show(); aber nicht das selbe da show die Kontrolle zurückgibt!
("[...]returns control to the caller immediately.")

Quelle:
http://qt-project.org/doc/qt-4.8/qdialog.html

So jetzt ist die Sache aber glasklar und ich hoffe es hilft auch anderen :-)
Gruß Meho
hilefoks
Beiträge: 144
Registriert: 13. März 2008 16:09

Re: Widget schließt ganzes Programm und nicht nur sich selbs

Beitrag von hilefoks »

Meho hat geschrieben:Aber genau deswegen leg ich das ja auf dem Stack und nicht auf den Heap ich möchte ja keine Datenmüllschleuder programmieren ;-).
Das ist ein wichtiger und guter Gedanke, aber es gibt auch genügend Wege mit dem Heap zu arbeiten, ohne Datenmüllschleudern zu programmieren. Dennoch - in deinem Fall ist von QDialog ableiten und exec() verwenden wohl der richtige Weg.
Meho hat geschrieben:Ich dachte wenn ich .setModal(true); setze wartet das Hauptprogramm und da dürfte die Funktion ja nicht weiterlaufen und es sich auch nicht beenden, so die Aussage in einem Forum.
Vorsicht! Wie auch in deinem Zitat der Qt-Doku ausgeführt ist, führt setModal(true) dazu, das die Eingaben in andere sichtbare Fenster der gleichen Anwendung blockiert werden. Das heißt aber nicht, das die Anwendung blockiert wird! Modale Fenster werden entsprechend schon vom Fenstermanager des Betriebssystems verwaltet. Der Fenstermanager verhindert also, das andere Fenster weitere Eingabe-Events erhalten, er verhindert aber nicht, das das Programm weiterläuft.
Antworten