Aufbau eines Projekts?!?
Aufbau eines Projekts?!?
Hallo,
ich hätte hier mal kurz eine grundlegende Frage zum Aufbau eines Projekts.
Gibt es eine Regel, nach welcher man ein Projekt aufbaut?
Bis jetzt dachte ich immer, man muss für die einzelnen "Kapitel" seines Projekts immer die Passenden Klassen und deren Funktionen in einer seperaten Header - Datei deklarieren, und in der dazu passenden cpp-Datei dann definieren.
Und dann gibt es noch eine Main-Datei, welche alle anderen Dateien includiert und die main-Funktion beinhaltet.
Jetzt habe ich aber herausgefunden, dass ich von einer cpp-Datei heraus Funktionen von einer anderen cpp-datei aufrufen kann, ohne diese includiert zu haben...wie kommt das?
Und muss ich dann in der main.h bzw. in der main.cpp überhaupt noch die ganzen anderen Dateien includiert haben oder nicht? Und was genau wird denn wo includiert?
Werden wichtige Header in die dazugehörige Header-Datei includiert oder in die cpp-Datei?
Und angenommen, ich habe eine Klasse, welche ich in 2 cpp-Dateien brauche, wie stelle ich das dann an, ohne doppelte Deklarationen zu vermeiden?
Und darf man eine Headerdatei in mehrere cpp-Dateien includieren?
Ich hoffe, mir kann hier jemand weiterhelfen!
Grüße
Gapa
ich hätte hier mal kurz eine grundlegende Frage zum Aufbau eines Projekts.
Gibt es eine Regel, nach welcher man ein Projekt aufbaut?
Bis jetzt dachte ich immer, man muss für die einzelnen "Kapitel" seines Projekts immer die Passenden Klassen und deren Funktionen in einer seperaten Header - Datei deklarieren, und in der dazu passenden cpp-Datei dann definieren.
Und dann gibt es noch eine Main-Datei, welche alle anderen Dateien includiert und die main-Funktion beinhaltet.
Jetzt habe ich aber herausgefunden, dass ich von einer cpp-Datei heraus Funktionen von einer anderen cpp-datei aufrufen kann, ohne diese includiert zu haben...wie kommt das?
Und muss ich dann in der main.h bzw. in der main.cpp überhaupt noch die ganzen anderen Dateien includiert haben oder nicht? Und was genau wird denn wo includiert?
Werden wichtige Header in die dazugehörige Header-Datei includiert oder in die cpp-Datei?
Und angenommen, ich habe eine Klasse, welche ich in 2 cpp-Dateien brauche, wie stelle ich das dann an, ohne doppelte Deklarationen zu vermeiden?
Und darf man eine Headerdatei in mehrere cpp-Dateien includieren?
Ich hoffe, mir kann hier jemand weiterhelfen!
Grüße
Gapa
Gestern war heute noch morgen!
So, erst mal ganz ruhig und Ordnung in die Gedankengaenge bringen !
Wichtig: Sich Fruehzeitig die Terminologien gewoehnen, dann tut man sich auch leichter wenn man Dokus liest. Und andere wissen auch schneller um was es geht, wenn man denen ein Problem schildert.
Also was genau meinst du mit "Kapitel" ?
in der eigentlichen header datei ...
das garantiert dir, das die headerdatei nur einmal pro uebersetzungseinheit gelesen wird, und dadurch das du sie ueberall da einfuegst wo sie gebraucht wird, auch gleich am anfang gelesen und übersetzt wird, wo sie das erste mal verwendet wird.
Bei normaler anwendungsenmtwicklung isses noch alles ganz human, aber wenn man Bibliotheken entwickelt, muss man ziemlich auf abhaengigkeiten achten ... dan wirds komplizierter ...
Ciao ....
Jein, es gibt eher Richtlinien ...Gibt es eine Regel, nach welcher man ein Projekt aufbaut?
Kapitel gibt es maximal bei der Dokumentation. Bei der Programmierung eher nichtman muss für die einzelnen "Kapitel" seines Projekts
Also was genau meinst du mit "Kapitel" ?
Dazu gibt es die "Include Guards" ! unter VS Studio das "#pragma once" ansonsten das "Und angenommen, ich habe eine Klasse, welche ich in 2 cpp-Dateien brauche, wie stelle ich das dann an, ohne doppelte Deklarationen zu vermeiden?
Code: Alles auswählen
#ifndef MYCLASSHEADER_H
#define MYCLASSHEADER_H
#endif // MYCLASSHEADER_H
das garantiert dir, das die headerdatei nur einmal pro uebersetzungseinheit gelesen wird, und dadurch das du sie ueberall da einfuegst wo sie gebraucht wird, auch gleich am anfang gelesen und übersetzt wird, wo sie das erste mal verwendet wird.
ist sogar ueblich ...Und darf man eine Headerdatei in mehrere cpp-Dateien includieren?
das ist gar ned mal so trivial zu beantworten ....Und was genau wird denn wo includiert?
Bei normaler anwendungsenmtwicklung isses noch alles ganz human, aber wenn man Bibliotheken entwickelt, muss man ziemlich auf abhaengigkeiten achten ... dan wirds komplizierter ...
Ciao ....
Re: Aufbau eines Projekts?!?
Dem Compiler müssen nur die Deklarationen (Headerdateien) bekannt sein, um das verbinden (Funktion in einer .cpp- aus einer anderen .cpp-Datei heraus aufrufen) kümmert sich der Linker. Du solltest daher niemals in eine .cpp-Datei eine andere .cpp-Datei includieren, nur die jeweilige Header-Datei.Gapa hat geschrieben: Jetzt habe ich aber herausgefunden, dass ich von einer cpp-Datei heraus Funktionen von einer anderen cpp-datei aufrufen kann, ohne diese includiert zu haben...wie kommt das?
Und muss ich dann in der main.h bzw. in der main.cpp überhaupt noch die ganzen anderen Dateien includiert haben oder nicht?
Projekt organisieren
Hallo,
erst mal vielen Dank für die hilfreichen Antworten!!
Jetzt habe ich noch 2 Fragen:
1.
Wie benutzt man gewöhnlich die main() - Funktion?? In meinem Projekt dient sie lediglich als "Aktivierer" für das Programm und am Ende als "Deaktivierer", d.h, dass ich von der main-Funktion aus mein erstes Fenster starten lasse, und dieses startet dann je nach Verlauf und Benutzereingabe weitere Fenster. Sobald ein neues Fenster geöffnet wird, sorgt das neue Fenster dafür, dass das alte Fenster geschlossen wird. Und wenn man irgendein Fenster schließt, so kehrt das Programm zu main-Funktion zurück und das Programm wird beendet.
Nun weiß ich jedoch nicht, ob das so sinnvoll ist. Denn ich könnte mir noch ein 2. Prinzip vorstellen, welches ich zwar ohne weiteres nicht in die Tat umzusetzen wüsste, doch es hört sich gut an:
Jedes Fenster (Einheit) springt immer erst wieder zur main-Funktion zurück, sobald es seine Aufgabe erledigt hat, und die main-Funktion ruft dann das neue Fenster (Einheit) auf... praktisch ein Stern-Prinzip (das andere wäre das Kreis-Prinzip
)
Welches Prinzip ist nun empfehlenswert?? Denn ich merke immer wieder, dass ich große Schwierigkeiten mit dem Gültigkeitsbereich von Objekten habe! Und mit meinem Prinzip müsste ich immer das alte Objekt an das neue mitübergeben... *ätzend*!!
2.
Wie schon erwähnt, habe ich große Probleme mit den Gültigkeitsbereichen von Objekten / Variablen.
Wenn ich Fenster Nr. 1 (von der main-Funktion aus) öffnen lasse, und von dort aus dann einen Thread starten lassen will, welcher sich in einer anderen cpp-Datei befindet, so bleibt mir ja nichts anderes übrig, als eine Funktion aus der anderen cpp-Datei aufzurufen, um den Thread mit den Informationen aus Fenster Nr. 1 zu initialisieren. Hier jedoch dann schon das Problem: Ich muss bereits ein Objekt der Klasse Thread definiert haben, denn ansonsten würde ich ja das Objekt erst in der aufgerufenen Funktion deklarieren / definieren --> das Objekt würde sobald die Funktion zurückkehrt wieder zerstört werden!!
Also wie umgehe ich hier diese globalen Variablen?? Ist es denn irgendwie möglich, ein Objekt in einer Funktion zu erstellen, und dieses nach Zurückkehren der Funktion noch zur Verfügung zu haben??
Viele Grüße
Gapa
erst mal vielen Dank für die hilfreichen Antworten!!
Jetzt habe ich noch 2 Fragen:
1.
Wie benutzt man gewöhnlich die main() - Funktion?? In meinem Projekt dient sie lediglich als "Aktivierer" für das Programm und am Ende als "Deaktivierer", d.h, dass ich von der main-Funktion aus mein erstes Fenster starten lasse, und dieses startet dann je nach Verlauf und Benutzereingabe weitere Fenster. Sobald ein neues Fenster geöffnet wird, sorgt das neue Fenster dafür, dass das alte Fenster geschlossen wird. Und wenn man irgendein Fenster schließt, so kehrt das Programm zu main-Funktion zurück und das Programm wird beendet.
Nun weiß ich jedoch nicht, ob das so sinnvoll ist. Denn ich könnte mir noch ein 2. Prinzip vorstellen, welches ich zwar ohne weiteres nicht in die Tat umzusetzen wüsste, doch es hört sich gut an:
Jedes Fenster (Einheit) springt immer erst wieder zur main-Funktion zurück, sobald es seine Aufgabe erledigt hat, und die main-Funktion ruft dann das neue Fenster (Einheit) auf... praktisch ein Stern-Prinzip (das andere wäre das Kreis-Prinzip
Welches Prinzip ist nun empfehlenswert?? Denn ich merke immer wieder, dass ich große Schwierigkeiten mit dem Gültigkeitsbereich von Objekten habe! Und mit meinem Prinzip müsste ich immer das alte Objekt an das neue mitübergeben... *ätzend*!!
2.
Wie schon erwähnt, habe ich große Probleme mit den Gültigkeitsbereichen von Objekten / Variablen.
Wenn ich Fenster Nr. 1 (von der main-Funktion aus) öffnen lasse, und von dort aus dann einen Thread starten lassen will, welcher sich in einer anderen cpp-Datei befindet, so bleibt mir ja nichts anderes übrig, als eine Funktion aus der anderen cpp-Datei aufzurufen, um den Thread mit den Informationen aus Fenster Nr. 1 zu initialisieren. Hier jedoch dann schon das Problem: Ich muss bereits ein Objekt der Klasse Thread definiert haben, denn ansonsten würde ich ja das Objekt erst in der aufgerufenen Funktion deklarieren / definieren --> das Objekt würde sobald die Funktion zurückkehrt wieder zerstört werden!!
Also wie umgehe ich hier diese globalen Variablen?? Ist es denn irgendwie möglich, ein Objekt in einer Funktion zu erstellen, und dieses nach Zurückkehren der Funktion noch zur Verfügung zu haben??
Viele Grüße
Gapa
Gestern war heute noch morgen!
die main ist einfach dein starter ...
quasi die funktion die nach dem laden des executables,initialisierung deines stacks und all die anderen startroutinen vom "programm" angesprungen wird.
die main muss ueberigens nicht main heissen, der name ist eigentlich frei, aber die meisten halten sich an konventionen.
muss halt nur beim zusammenbauen(linken) bekannt sein und die parameter muessen stimmen
wie man die benutzt ist auch geschmackssache.
wobei man da scho zwischen GUI und nichtgui(konsole / server) programmen unterscheiden sollt.
die meisten nichtgui programme sind funktions, methodenorientiert, das heisst die laufen durch reine funktionsaufrufe ab.
GUI programme sind meist eventorientiert und haben ne Eventschleife (msg pump). das heisst man kreiert (meist impliziet) eine solche (QApplication z.b.) und schickt den aufruf dann in die schleife. (exec() methoden unter qt). Ab dann "reagiert" man nur noch auf events.
mit nem close() auf das mainobject kann man der schleife sagen, das sie sich beenden soll, und dann laeuft das programm einfach aus ...
Also nen App object und das mainwindows erzeugen, in den konstrukturen der widgets die hirarchie (subwindows) aufbauen ... und wenn der konstruktur durch ist, die eventschleife zu starten, ist durchaus gaengige praxis in QT .... auch bei groesseren Projekten.
Optional kommen meist nur noch zusaetzliche initialisierungen hinzu.
du erstellst die application, das hauptfenster, im hauptfenster-konstruktor die unterfenster, dann betrittst die eventloop.
ab dann reagierst du auf events und bei bestimmten events koennen unter anderm fenster neu erzeugt werden ...
das ist der qt weg.
bei anderen frameworks(mfc z.b.) kann wird dir sogar das erstellen der anwendung und des hauptfensterns abgenommen du musst dann eine klasse vom typ Application meist ableiten, und kannst mit der auf events (virtuelle methoden) reagieren und so dein verhalten implementieren. da brauchst / darfst gar keine main schreiben, weil das macht das framework.
Bist du sicher das du schon mit threads arbeiten "willst" ??? fuer threads und deren probleme sollt man scho zeimlich sattelfest sein. Damit mein ich zwar auch c++ als sprache, aber noch mehr die vorgaenge im BS, wie und wo variablen angelegt werden, wie der stack funktioniert, wie dynamische librariers funktioniern etc. Und vor allem, wann genau Objecte(instanzen) erzeugt werden und wie lange sie leben. Besonders bei implizieten/indirekten objecten (temporare objecte, lokale variablen und ihr geltungsbereich, funktions-parameter).
Bevor du mit threads anfaengst, solltes da wirklich nen fundamentales wissen haben, ansonsten probierst dich und den hauptspeicher deines rechners tot ^^
Und als programmieren wuerd ich das dann auch ned mehr bezeichnen ^^
Ciao ...
quasi die funktion die nach dem laden des executables,initialisierung deines stacks und all die anderen startroutinen vom "programm" angesprungen wird.
die main muss ueberigens nicht main heissen, der name ist eigentlich frei, aber die meisten halten sich an konventionen.
muss halt nur beim zusammenbauen(linken) bekannt sein und die parameter muessen stimmen
wie man die benutzt ist auch geschmackssache.
wobei man da scho zwischen GUI und nichtgui(konsole / server) programmen unterscheiden sollt.
die meisten nichtgui programme sind funktions, methodenorientiert, das heisst die laufen durch reine funktionsaufrufe ab.
GUI programme sind meist eventorientiert und haben ne Eventschleife (msg pump). das heisst man kreiert (meist impliziet) eine solche (QApplication z.b.) und schickt den aufruf dann in die schleife. (exec() methoden unter qt). Ab dann "reagiert" man nur noch auf events.
mit nem close() auf das mainobject kann man der schleife sagen, das sie sich beenden soll, und dann laeuft das programm einfach aus ...
Also nen App object und das mainwindows erzeugen, in den konstrukturen der widgets die hirarchie (subwindows) aufbauen ... und wenn der konstruktur durch ist, die eventschleife zu starten, ist durchaus gaengige praxis in QT .... auch bei groesseren Projekten.
Optional kommen meist nur noch zusaetzliche initialisierungen hinzu.
genau so funktioniert nen gui programm nicht !Jedes Fenster (Einheit) springt immer erst wieder zur main-Funktion zurück, sobald es seine Aufgabe erledigt hat, und die main-Funktion ruft dann das neue Fenster (Einheit) auf... praktisch ein Stern-Prinzip (das andere wäre das Kreis-Prinzip Very Happy )
du erstellst die application, das hauptfenster, im hauptfenster-konstruktor die unterfenster, dann betrittst die eventloop.
ab dann reagierst du auf events und bei bestimmten events koennen unter anderm fenster neu erzeugt werden ...
das ist der qt weg.
bei anderen frameworks(mfc z.b.) kann wird dir sogar das erstellen der anwendung und des hauptfensterns abgenommen du musst dann eine klasse vom typ Application meist ableiten, und kannst mit der auf events (virtuelle methoden) reagieren und so dein verhalten implementieren. da brauchst / darfst gar keine main schreiben, weil das macht das framework.
Bist du sicher das du schon mit threads arbeiten "willst" ??? fuer threads und deren probleme sollt man scho zeimlich sattelfest sein. Damit mein ich zwar auch c++ als sprache, aber noch mehr die vorgaenge im BS, wie und wo variablen angelegt werden, wie der stack funktioniert, wie dynamische librariers funktioniern etc. Und vor allem, wann genau Objecte(instanzen) erzeugt werden und wie lange sie leben. Besonders bei implizieten/indirekten objecten (temporare objecte, lokale variablen und ihr geltungsbereich, funktions-parameter).
Bevor du mit threads anfaengst, solltes da wirklich nen fundamentales wissen haben, ansonsten probierst dich und den hauptspeicher deines rechners tot ^^
Und als programmieren wuerd ich das dann auch ned mehr bezeichnen ^^
Ciao ...
QMainWindow / QWidget /QDialog
Hallo,
also echt super! Gott sei Dank ist es nicht das Stern-Prinzip^^, sonst hätte ich alles umstrukturieren müssen...
Und ich schätze, dass ich die Probleme mit den Gültigkeitsbereichsüberschreitungen mit QMainWindow auch noch in den Griff bekomme, denn dieses habe ich bisher nicht benutzt!
In meinem Buch benutze ich stets nur QWidget...klar, denn ich hab ja auch nie mehr als ein Fenster in den Beispielen im Buch!!!
Also ist es ratsam, immer ein Hauptfenster mit QMainWindow zu erstellen, und dann alle folgenden Nebenfenster quasi als "Unterfenster" zu definieren??
Wenn ja, dann ergeben sich bei mir schon die ersten Fragen:
1. Angenommen, mein Hauptfenster kommt nicht als erstes...muss ich dann mehrere Fenster auf einmal erstellen lassen und alle bis auf das aktuelle Fenster "verstecken" ?? Oder wie stelle ich es sonst an, dass mein "Einleitungs - oder Startfenster" ein Unterfenster des Hauptfensters ist, welches noch gar nicht existiert??
2. Angenommen, ich habe keine wirklichen Hauptfenster, sondern nur 2 - 3 Nebenfenster...muss ich dann trotzdem eines dieser Fenster zum Hauptfenster "ernennen" ?? Klar, es wäre ja kein Problem, aber irgendwie würde es mich stören...ihr wisst ja, was ich meine, oder
Und was gibt es noch so für Fensterklassen??
Und was passiert eigentlich, wenn ich QApplication ausführen lasse?? Das ist doch nicht etwas wie ein Fenster, oder?? Benötigt man das etwa, um Guis anzeigen lassen zu können, oder kann man QApplication auch iwi umgehen??
Ich hoffe jemand kann mir diese Fragen noch beantworten!!
Viele Grüße
Gapa
also echt super! Gott sei Dank ist es nicht das Stern-Prinzip^^, sonst hätte ich alles umstrukturieren müssen...
Und ich schätze, dass ich die Probleme mit den Gültigkeitsbereichsüberschreitungen mit QMainWindow auch noch in den Griff bekomme, denn dieses habe ich bisher nicht benutzt!
In meinem Buch benutze ich stets nur QWidget...klar, denn ich hab ja auch nie mehr als ein Fenster in den Beispielen im Buch!!!
Also ist es ratsam, immer ein Hauptfenster mit QMainWindow zu erstellen, und dann alle folgenden Nebenfenster quasi als "Unterfenster" zu definieren??
Wenn ja, dann ergeben sich bei mir schon die ersten Fragen:
1. Angenommen, mein Hauptfenster kommt nicht als erstes...muss ich dann mehrere Fenster auf einmal erstellen lassen und alle bis auf das aktuelle Fenster "verstecken" ?? Oder wie stelle ich es sonst an, dass mein "Einleitungs - oder Startfenster" ein Unterfenster des Hauptfensters ist, welches noch gar nicht existiert??
2. Angenommen, ich habe keine wirklichen Hauptfenster, sondern nur 2 - 3 Nebenfenster...muss ich dann trotzdem eines dieser Fenster zum Hauptfenster "ernennen" ?? Klar, es wäre ja kein Problem, aber irgendwie würde es mich stören...ihr wisst ja, was ich meine, oder
Und was gibt es noch so für Fensterklassen??
Und was passiert eigentlich, wenn ich QApplication ausführen lasse?? Das ist doch nicht etwas wie ein Fenster, oder?? Benötigt man das etwa, um Guis anzeigen lassen zu können, oder kann man QApplication auch iwi umgehen??
Ich hoffe jemand kann mir diese Fragen noch beantworten!!
Viele Grüße
Gapa
Gestern war heute noch morgen!
Definier mal "nebenfenster" genauer
Alle GUI's die ich kenne arbeiten hirarisch, das heisst es besteht eine Baumstruktur der Fenster. Das ist unter anderem fuer die Nachrichtenverwaltung wichtig, und auch fuer das handling. Loeschst Du das oberste Fenster, sollten alle Deine Unterfenster (Childs) mit geschlossen werden.
Um da aber ein Gefuehl fuer zu bekommen, wuerd ich Dir literatur ueber die win32 API empfehlen ... da ist das wirklich Basics. Der X Server verwendet das selbe Prinzip, aber irgednwie ists schwerer dafuer gescheite literatur zu bekommen.
Weiterhin, eine Parent-Child beziehung ist nicht bedingt durch das einbetten eines Fensters in ein anderes, also die typische Fenster-Controls Geschichte. sondern nur durch verhandensein von paar beziehungen.
Beispiel, eine MessageBox kann und ist meist nen child von nem anderen fensterobject. Aber trotzdem wird die losgeloest von dem fenster dargestellt. man kann die verschieben etc.
Das einzigste was ne parent child Beziehung nach aussen bedingt, ist der lebenszyklus. Nen child was seinen Parent "ueberlebt" sollt es ned geben, das macht immer probleme.
Programmiertechnisch sind parent child bedingungen da, um "einfach" nachrichten zwischen den fenstern auszutauschen. So das man in einem Fenster auf Eingaben im anderen fenster reagieren kann, z.b.
Den eventmechanismuss koennt man aber auch anderweitig nachbilden .... mit eigenen events oder gar IPC, nur wird das komplexer.
Theorethisch kann man 3 Hauptfenster in eine Anwendung pappen, nur praktisch macht das eigentlich ned viel sinn ....
3 Hauptfenster bedeutet, du kannst sie getrennt schliessen, ohne das sie sich dadurch gegenseitig beeinflussen.
Die frage ist, wenn du wirklich sowas brauchst, warum dann nicht 3 Applikationen mit jeweil einem hauptfenster ???
Du kannst aber 1 Hauptfenster und 2 oder mehrere subfenster (Dialogs in dem fall) machen, die losgeloest vom hauptfenster agieren, aber wenn das hauptfenster schliests, muessen die auch weg.
Gnome anwendungen, gimp z.b. verwenden sowas, die ausgelagaerten werkzeugleisten und so ...
Der Knackpunkt deines geschilderten problems .... alle deine potentiellen "Hauptfenster" sind nie zur gleichen zeit sichtbar.
d.h. es bieten sich paar loesungs-moeglichkeiten an ....
1. du teilst dein Programm in mehrere Schritte(funktion), in jedem der Schritte (funktionen) erstellst du nen ApplicationsObject und nen Hauptfenster. Wenn die Application aus dem exit() zurueckkommt, springst du auch in der funktion zurueck.
in der main springs nur alle Schritte (FUnktionen) hintereinander an.
Das ist wie wenn du mehrere Programme hintereinander ausfuehrst.
2. du baust nur 1 applicationsobject.
verbindest das close Signal von den ersten fenstern ned mit dem close der applikation sondern von nem eigenen Slot, und in dem slot erstellst das Nachfolgende fenster und laesst es anzeigen (show()) .... danach das naechste ... etc.
Die QWidgets intern referenzieren alle auf ein "globales" QApplication object (Eher nen global verfuegbares makro, welches das aktuelle QApplication object verfuegbar macht)
d.h. Qwidgets ohne QApplication geht ned (fuer reine Qt Programme eh kein Problem, aber leute die einfach Qt-Dialoge/Wigets in vorhandene Programme ohne QT einbetten muessen, plugins z.b. , muessen sich mit diesem Umstand expliziet beschaeftigen). Und es duerfen auch keine 2 Application objecte fuer die Uebersetzungseinheit gleichzeitig existieren(fuer das Makro muss immer ein eindeutiges QApp object verfuegbar sein) ....
QMainWindow (wenn es menuleiste Statusbar Toolbar etc haben soll),
QDialog(fuer Dialoge aller Art, Ohne eigene Menu und toolbars meistens ),
QDockWidgets(Werkzeugleisten, die auch ausm Mainwindow ausgeklinkt werden koennen, und damit freistehend sein koennen)
falls man selber man eigenes Fenster mit eher nichtsosehr standardisierten verhalten bauen will, kann man von QWidget ableiten und mittels den fensterflags dem so fast alles auf dem Fenstaermanager möglichen verhalten beibringen .... sollt man aber wirklich nur in ausnahmefaellen machen.
BTW. die QT ist nen Framework fuer nen eher standardisiertes Look und feel.
Will man besonderes Feeling implementieren, stellt sich immer die frage nach der berechtigung der lib. weil meist hat man mit der dann mehr abreit als wie es einem vorteile bringt.
Aber so Wizards(aufeinanderfolgende fenster), EInleitungsfenster etc. beissen sich natuerlich ned mit der qt Philosphie. ALso in deinem fall kannst scho bei der qt bleiben.
Ciao ...
Alle GUI's die ich kenne arbeiten hirarisch, das heisst es besteht eine Baumstruktur der Fenster. Das ist unter anderem fuer die Nachrichtenverwaltung wichtig, und auch fuer das handling. Loeschst Du das oberste Fenster, sollten alle Deine Unterfenster (Childs) mit geschlossen werden.
Um da aber ein Gefuehl fuer zu bekommen, wuerd ich Dir literatur ueber die win32 API empfehlen ... da ist das wirklich Basics. Der X Server verwendet das selbe Prinzip, aber irgednwie ists schwerer dafuer gescheite literatur zu bekommen.
Weiterhin, eine Parent-Child beziehung ist nicht bedingt durch das einbetten eines Fensters in ein anderes, also die typische Fenster-Controls Geschichte. sondern nur durch verhandensein von paar beziehungen.
Beispiel, eine MessageBox kann und ist meist nen child von nem anderen fensterobject. Aber trotzdem wird die losgeloest von dem fenster dargestellt. man kann die verschieben etc.
Das einzigste was ne parent child Beziehung nach aussen bedingt, ist der lebenszyklus. Nen child was seinen Parent "ueberlebt" sollt es ned geben, das macht immer probleme.
Programmiertechnisch sind parent child bedingungen da, um "einfach" nachrichten zwischen den fenstern auszutauschen. So das man in einem Fenster auf Eingaben im anderen fenster reagieren kann, z.b.
Den eventmechanismuss koennt man aber auch anderweitig nachbilden .... mit eigenen events oder gar IPC, nur wird das komplexer.
Theorethisch kann man 3 Hauptfenster in eine Anwendung pappen, nur praktisch macht das eigentlich ned viel sinn ....
3 Hauptfenster bedeutet, du kannst sie getrennt schliessen, ohne das sie sich dadurch gegenseitig beeinflussen.
Die frage ist, wenn du wirklich sowas brauchst, warum dann nicht 3 Applikationen mit jeweil einem hauptfenster ???
Du kannst aber 1 Hauptfenster und 2 oder mehrere subfenster (Dialogs in dem fall) machen, die losgeloest vom hauptfenster agieren, aber wenn das hauptfenster schliests, muessen die auch weg.
Gnome anwendungen, gimp z.b. verwenden sowas, die ausgelagaerten werkzeugleisten und so ...
Also ein definitives, Ja es ist ratsam. Es gaenge auch anders, aber das ist "schmerzhafter"Also ist es ratsam, immer ein Hauptfenster mit QMainWindow zu erstellen, und dann alle folgenden Nebenfenster quasi als "Unterfenster" zu definieren??
Hier kannst du ne mischung aus console und GUI programm fahren ....Oder wie stelle ich es sonst an, dass mein "Einleitungs - oder Startfenster" ein Unterfenster des Hauptfensters ist, welches noch gar nicht existiert??
Der Knackpunkt deines geschilderten problems .... alle deine potentiellen "Hauptfenster" sind nie zur gleichen zeit sichtbar.
d.h. es bieten sich paar loesungs-moeglichkeiten an ....
1. du teilst dein Programm in mehrere Schritte(funktion), in jedem der Schritte (funktionen) erstellst du nen ApplicationsObject und nen Hauptfenster. Wenn die Application aus dem exit() zurueckkommt, springst du auch in der funktion zurueck.
in der main springs nur alle Schritte (FUnktionen) hintereinander an.
Das ist wie wenn du mehrere Programme hintereinander ausfuehrst.
2. du baust nur 1 applicationsobject.
verbindest das close Signal von den ersten fenstern ned mit dem close der applikation sondern von nem eigenen Slot, und in dem slot erstellst das Nachfolgende fenster und laesst es anzeigen (show()) .... danach das naechste ... etc.
QApplication ist dein holder deiner Evnetschleife ... ohne die geht Gar nix, zu deutsch: die fenster innerhalb deiner hirarchie koennten ned miteinander kommunizieren. du koenntest bei den fenstern druecken was willst es wuerd gar nix passieren.Und was passiert eigentlich, wenn ich QApplication ausführen lasse?? Das ist doch nicht etwas wie ein Fenster, oder?? Benötigt man das etwa, um Guis anzeigen lassen zu können, oder kann man QApplication auch iwi umgehen
Die QWidgets intern referenzieren alle auf ein "globales" QApplication object (Eher nen global verfuegbares makro, welches das aktuelle QApplication object verfuegbar macht)
d.h. Qwidgets ohne QApplication geht ned (fuer reine Qt Programme eh kein Problem, aber leute die einfach Qt-Dialoge/Wigets in vorhandene Programme ohne QT einbetten muessen, plugins z.b. , muessen sich mit diesem Umstand expliziet beschaeftigen). Und es duerfen auch keine 2 Application objecte fuer die Uebersetzungseinheit gleichzeitig existieren(fuer das Makro muss immer ein eindeutiges QApp object verfuegbar sein) ....
Fuer "freistehende" Fenster verwendet man meist:Und was gibt es noch so für Fensterklassen??
QMainWindow (wenn es menuleiste Statusbar Toolbar etc haben soll),
QDialog(fuer Dialoge aller Art, Ohne eigene Menu und toolbars meistens ),
QDockWidgets(Werkzeugleisten, die auch ausm Mainwindow ausgeklinkt werden koennen, und damit freistehend sein koennen)
falls man selber man eigenes Fenster mit eher nichtsosehr standardisierten verhalten bauen will, kann man von QWidget ableiten und mittels den fensterflags dem so fast alles auf dem Fenstaermanager möglichen verhalten beibringen .... sollt man aber wirklich nur in ausnahmefaellen machen.
BTW. die QT ist nen Framework fuer nen eher standardisiertes Look und feel.
Will man besonderes Feeling implementieren, stellt sich immer die frage nach der berechtigung der lib. weil meist hat man mit der dann mehr abreit als wie es einem vorteile bringt.
Aber so Wizards(aufeinanderfolgende fenster), EInleitungsfenster etc. beissen sich natuerlich ned mit der qt Philosphie. ALso in deinem fall kannst scho bei der qt bleiben.
Ciao ...
QWidget / QMainWindow
Hallo,
Tausend Dank für die ausführliche Antwort!! Live Support pur hier!!!
Ich glaube jedoch, dass ich den Aufbau und den Sinn eines QWidget-Fensters noch nicht richtig verstanden habe.
Angenommen, ich erstelle einfach nur mit dem Befehl QWidget *MyWidget = new QWidget
ein Fenster ohne Buttons, Labels etc.
Was habe ich dann? Habe ich dann nur einen blauen Rahmen oder einen blauen Rahmen und einen grauen Hintergrund??
Wenn ich jedoch den Befehl QMainWindow *MyMainWindow = new QMainWindow nehme, was ist dann der Unterschied zwischen diesem Fenster und dem MyWidget-Fenster??
Also ich schildere mal wie ich das ganze "Mysterium" verstehe:
QWidget ist quasi die "Ursprungsklasse" für alle Arten von Fensten. Wenn man nun ein neues Projekt erstellt hat man 2 Möglichkeiten, ein bzw. mehrere Fenster zu erstellen:
Mögl. 1:
Man erstellt ein völlig neues, nach eingenen Gedanken aussehendes Fenster, indem man es einfach nur von QWidget ableitet, d.h, dass QWidget kein Layout ist, sondern einfach nur das Grundgerüst eines jeden Fensters (Blauer Rahmen mit Minimieren, Maximieren, Schließen; KEIN Inhalt).
Mögl. 2:
Man benutzt vorgefertigte Layouts wie z.B QMainWindow, welche auch von QWidget erstellt wurden, jedoch noch ein paar Extras haben wie einen Hintergrund (typisch grau), Statusleiste, Menüleiste etc.
Nur komme ich mit dieser Theorie nicht ganz klar, denn wenn ich mal einfach ein QWidget erstelle, ohne irgendwelche anderen Extras, so habe ich ein Fenster mit Hintergrund!!
Jedoch meine ich, dass dieser Hintergrund nicht immer in einem Fenster enthalten sein muss, denn ich hatte es schon geschafft, dass mein Fenster nicht den typisch "braungrauen" Hintergrund hat, sondern einen richtig dunkelgrauen Hintergrund...wisst ihr von was ich rede??
Ich verstehe wohl einfach nicht, was ein QWidget-Fenster ist im Vgl. zu QMainWindows, QDialogs etc..
Könntet ihr mir da weiterhelfen??
Viele Grüße
Gapa
Tausend Dank für die ausführliche Antwort!! Live Support pur hier!!!
Ich glaube jedoch, dass ich den Aufbau und den Sinn eines QWidget-Fensters noch nicht richtig verstanden habe.
Angenommen, ich erstelle einfach nur mit dem Befehl QWidget *MyWidget = new QWidget
ein Fenster ohne Buttons, Labels etc.
Was habe ich dann? Habe ich dann nur einen blauen Rahmen oder einen blauen Rahmen und einen grauen Hintergrund??
Wenn ich jedoch den Befehl QMainWindow *MyMainWindow = new QMainWindow nehme, was ist dann der Unterschied zwischen diesem Fenster und dem MyWidget-Fenster??
Also ich schildere mal wie ich das ganze "Mysterium" verstehe:
QWidget ist quasi die "Ursprungsklasse" für alle Arten von Fensten. Wenn man nun ein neues Projekt erstellt hat man 2 Möglichkeiten, ein bzw. mehrere Fenster zu erstellen:
Mögl. 1:
Man erstellt ein völlig neues, nach eingenen Gedanken aussehendes Fenster, indem man es einfach nur von QWidget ableitet, d.h, dass QWidget kein Layout ist, sondern einfach nur das Grundgerüst eines jeden Fensters (Blauer Rahmen mit Minimieren, Maximieren, Schließen; KEIN Inhalt).
Mögl. 2:
Man benutzt vorgefertigte Layouts wie z.B QMainWindow, welche auch von QWidget erstellt wurden, jedoch noch ein paar Extras haben wie einen Hintergrund (typisch grau), Statusleiste, Menüleiste etc.
Nur komme ich mit dieser Theorie nicht ganz klar, denn wenn ich mal einfach ein QWidget erstelle, ohne irgendwelche anderen Extras, so habe ich ein Fenster mit Hintergrund!!
Jedoch meine ich, dass dieser Hintergrund nicht immer in einem Fenster enthalten sein muss, denn ich hatte es schon geschafft, dass mein Fenster nicht den typisch "braungrauen" Hintergrund hat, sondern einen richtig dunkelgrauen Hintergrund...wisst ihr von was ich rede??
Ich verstehe wohl einfach nicht, was ein QWidget-Fenster ist im Vgl. zu QMainWindows, QDialogs etc..
Könntet ihr mir da weiterhelfen??
Viele Grüße
Gapa
Gestern war heute noch morgen!
Re: QWidget / QMainWindow
QWidget ist kein Fenster. QWidgetist die Basisklasse für alles was sichtbar ist, also zur grafischen Oberfläche gehört. Ein QWidget kann demnach alles werden, ein Button, ein Label oder eben auch ein Fenster.Gapa hat geschrieben:Ich glaube jedoch, dass ich den Aufbau und den Sinn eines QWidget-Fensters noch nicht richtig verstanden habe.
Widgets
Hallo,
und welches Element bzw. Widget sorgt dann für den blauen Rahmen und den grauen Hintergrund???
Angenommen, ich habe nur ein Objekt der Klasse QApplication erzeugt, dann habe ich ja noch nichts sichtbares (also keine Fenster, Rahmen, Widgets etc.)...
Wenn ich nun einfach mal eine von QWidget abgeleitete Klasse erstelle, in der ich einfach nur einen QPushButton erstellen lasse, welches Element sorgt dann für den blauen Rahmen und den Hintergrund und die Standartgröße des Fensters?? Und wieso wird dann nur der Hintergrund angezeigt, jedoch kein Button...der Button wird erst angezeigt, wenn ich ihn als Child angebe...jedoch müsste ich dazu erstmal ein Parent haben...aber was sollte das dann bitte sein?? Ich erzeuge ja schließlich nur den Button...
Ich hoffe da kann mal jemand Licht ins Dunkel bringen!
Grüße
Gapa
und welches Element bzw. Widget sorgt dann für den blauen Rahmen und den grauen Hintergrund???
Angenommen, ich habe nur ein Objekt der Klasse QApplication erzeugt, dann habe ich ja noch nichts sichtbares (also keine Fenster, Rahmen, Widgets etc.)...
Wenn ich nun einfach mal eine von QWidget abgeleitete Klasse erstelle, in der ich einfach nur einen QPushButton erstellen lasse, welches Element sorgt dann für den blauen Rahmen und den Hintergrund und die Standartgröße des Fensters?? Und wieso wird dann nur der Hintergrund angezeigt, jedoch kein Button...der Button wird erst angezeigt, wenn ich ihn als Child angebe...jedoch müsste ich dazu erstmal ein Parent haben...aber was sollte das dann bitte sein?? Ich erzeuge ja schließlich nur den Button...
Ich hoffe da kann mal jemand Licht ins Dunkel bringen!
Grüße
Gapa
Gestern war heute noch morgen!
Auch wenn die Gefahr besteht die Antwort würde als nicht hilfreich klassifiziert, so sei doch auf die Doku verwiesen. Sie ist sehr hilfreich, ausführlich, und was Besseres habe ich bisher nicht gefunden. Nur mal als Beispiel der Konstruktor von QWidget:
Man beachte den 2. Absatz, das sollte schon mal ein paar Fragen beantworten.QWidget::QWidget ( QWidget * parent = 0, Qt::WindowFlags f = 0 )
Constructs a widget which is a child of parent, with widget flags set to f.
If parent is 0, the new widget becomes a window. If parent is another widget, this widget becomes a child window inside parent. The new widget is deleted when its parent is deleted.
Nen QWidget unter der qt ist ne eigene lauffaehige klasse ... ergo sie implementiert alle von einem QWidget erwarteten funktionen in einer Defaultimplementation.
Ergo fuer alles was du siehst ist qwidget oder qobject (Basis von qwidget) verantwortlich.
Es stellt aber ne menge funktionalitaet bereit, um dieses Aussehen anpassen zu koennen.
Trotzdem solltwe man qwidget, bis auf ganz speziellen Ausnahmen, ned direkt instanzieieren (also ein new Qwidget ... aufrufen). Damit ist QWidget mehr eine Schnittstelle als eine implementierung.
Normal wird man immer die weiter spezialisierteren Klassen verwenden, die natuerlich andere einstellungen fuer die darstellung verwenden koennen.
Bei der fortgeschrittenen QT programmierung sollt man QWidget verwenden in dem man davon ableitet, ned das Ding zu instanziieren.
Die ausnahme wo man Qwidgets direkt verwenden kann/koennte, ist wenn man nen Platzhalter fuer nen layout braucht. Sprich du willst zur Laufzeit irgendwo eigene widgets einklinken, brauchst zur designzeit also nen platzhalter ...
Ansonsten wird man fast immer nur von qWidget abgeleitete klassen instaniziieren.
Ciao ...
Ergo fuer alles was du siehst ist qwidget oder qobject (Basis von qwidget) verantwortlich.
Es stellt aber ne menge funktionalitaet bereit, um dieses Aussehen anpassen zu koennen.
Trotzdem solltwe man qwidget, bis auf ganz speziellen Ausnahmen, ned direkt instanzieieren (also ein new Qwidget ... aufrufen). Damit ist QWidget mehr eine Schnittstelle als eine implementierung.
Normal wird man immer die weiter spezialisierteren Klassen verwenden, die natuerlich andere einstellungen fuer die darstellung verwenden koennen.
Bei der fortgeschrittenen QT programmierung sollt man QWidget verwenden in dem man davon ableitet, ned das Ding zu instanziieren.
Die ausnahme wo man Qwidgets direkt verwenden kann/koennte, ist wenn man nen Platzhalter fuer nen layout braucht. Sprich du willst zur Laufzeit irgendwo eigene widgets einklinken, brauchst zur designzeit also nen platzhalter ...
Ansonsten wird man fast immer nur von qWidget abgeleitete klassen instaniziieren.
Ciao ...
Baumstruktur
Hallo nochmal,
also ich glaube ich komme einfach noch nicht mit dem "Richtigen Aufbauen" meines Projekts klar.
Hier mal die Fakten:
- Ich habe in meinem Projekt 2 Fenster.
- Das 2. Fenster sollte das Hauptfenster sein
- in das 1. Fenster werden für das 2. Fenster wichtige Infos eingegeben
- Sobald das 1. Fenster (Konfigurationsfenster) erscheint, und die Daten korrekt eingetragen wurden und ein Absendebutton gedrückt wurde, soll es "verschwinden", d.h nicht zerstört werden, sondern unsichtbar werden - und das 2. Fenster (also das Hauptfenster) soll erstellt werden mit den aus Fenster 1 gewählten Daten
Ich habe jedoch einfach keinen Schimmer, wie ich das machen soll, denn ich bekomme immer Probleme mit den Gültigkeitsbereichen.
Wo und wann wird z.B. Fenster 2 deklariert und wo und wann wird es definiert bzw. aufgerufen??
Und brauche ich dafür nun 2 QApplication-Objekte?? Ist das dann doch die Stern-Methode oder nicht??
Könnte mir da mal jemand nen "groben" Plan machen, in dem gerade diese Fragen beantwortet werden und der den richtigen Aufbau "grob" schildert?
Das wäre echt super!
Viele Grüße
Gapa
also ich glaube ich komme einfach noch nicht mit dem "Richtigen Aufbauen" meines Projekts klar.
Hier mal die Fakten:
- Ich habe in meinem Projekt 2 Fenster.
- Das 2. Fenster sollte das Hauptfenster sein
- in das 1. Fenster werden für das 2. Fenster wichtige Infos eingegeben
- Sobald das 1. Fenster (Konfigurationsfenster) erscheint, und die Daten korrekt eingetragen wurden und ein Absendebutton gedrückt wurde, soll es "verschwinden", d.h nicht zerstört werden, sondern unsichtbar werden - und das 2. Fenster (also das Hauptfenster) soll erstellt werden mit den aus Fenster 1 gewählten Daten
Ich habe jedoch einfach keinen Schimmer, wie ich das machen soll, denn ich bekomme immer Probleme mit den Gültigkeitsbereichen.
Wo und wann wird z.B. Fenster 2 deklariert und wo und wann wird es definiert bzw. aufgerufen??
Und brauche ich dafür nun 2 QApplication-Objekte?? Ist das dann doch die Stern-Methode oder nicht??
Könnte mir da mal jemand nen "groben" Plan machen, in dem gerade diese Fragen beantwortet werden und der den richtigen Aufbau "grob" schildert?
Das wäre echt super!
Viele Grüße
Gapa
Gestern war heute noch morgen!
-
Ginsengelf
- Beiträge: 79
- Registriert: 2. Mai 2007 10:21
Moin, ganz grobes Beispiel, wie man das machen könnten (gibt sicher auch noch x Dutzend andere Wege):
Du erstellst ein QApplication-Objekt in main(), und da auch ein Fenster2-Objekt. Desses Konstruktor ruft dann Fenster1 als Dialog auf:
Dieses Beispiel erhebt keinen Anspruch auf Kompilierbarkeit.
Ginsengelf
Du erstellst ein QApplication-Objekt in main(), und da auch ein Fenster2-Objekt. Desses Konstruktor ruft dann Fenster1 als Dialog auf:
Code: Alles auswählen
Fenster2::Fenster2 () : QMainWindow ()
{
m_pFenster1 = new Fenster1();
int ret = m_pFenster1->exec (); // vorausgesetzt, dass Fenster1 von QDialog erbt
if (ret == QDialog::Accepted)
{
m_pFenster1->hide ();
// Daten aus m_pFenster1 holen und eintragen
}
}
Ginsengelf
Accept
Hallo,
AH!
accept() ist also die Möglichkeit, die ich schon lange gesucht habe, um aus einem Fenster wieder zurückzukehren ohne es gleich schließen zu müssen, denn bisher konnte ich immer nur mit dem close() - Befehl zurückkehren!
Wenn du mir jetzt noch sagen könntest, ob das mit dieser accept()-Funktion auch bei QWidget - abgeleiteten Klassen geht, denn ich will nicht von QDialog ableiten...
EDIT:
Und wie ist es möglich, aus einem Fenster heraus ein anderes Fenster zu erstellen?
Ich habe ein Fenster erstellen lassen, welches auf Knopfdruck ein anderes Fenster erstellt und per fenster.show() anzeigen lässt.
Jedoch blinkt das neue Fenster nur kurz auf und wird sofort wieder zerstört, wieso? Liegt das daran, dass der app.exec() - Befehl fehlt? Aber ich komme aus meiner Funktion weder an das app-Objekt heran, noch würde das etwas bringen, da es ja bereits aufgerufen wurde.
Und 2 QApplication-Objekte darf man ja nicht parallel laufen lassen...also wie mache ich das dann?
..Aber bitte Frage 1 auch beantworten
Viele Grüße
Gapa
AH!
accept() ist also die Möglichkeit, die ich schon lange gesucht habe, um aus einem Fenster wieder zurückzukehren ohne es gleich schließen zu müssen, denn bisher konnte ich immer nur mit dem close() - Befehl zurückkehren!
Wenn du mir jetzt noch sagen könntest, ob das mit dieser accept()-Funktion auch bei QWidget - abgeleiteten Klassen geht, denn ich will nicht von QDialog ableiten...
EDIT:
Und wie ist es möglich, aus einem Fenster heraus ein anderes Fenster zu erstellen?
Ich habe ein Fenster erstellen lassen, welches auf Knopfdruck ein anderes Fenster erstellt und per fenster.show() anzeigen lässt.
Jedoch blinkt das neue Fenster nur kurz auf und wird sofort wieder zerstört, wieso? Liegt das daran, dass der app.exec() - Befehl fehlt? Aber ich komme aus meiner Funktion weder an das app-Objekt heran, noch würde das etwas bringen, da es ja bereits aufgerufen wurde.
Und 2 QApplication-Objekte darf man ja nicht parallel laufen lassen...also wie mache ich das dann?
..Aber bitte Frage 1 auch beantworten
Viele Grüße
Gapa
Gestern war heute noch morgen!