Qt - Layout

Dieses Thema im Forum "C/C++" wurde erstellt von Barade, 16.04.2008.

  1. Barade

    Barade Kellerkind

    Dabei seit:
    14.12.2007
    Beiträge:
    24
    Zustimmungen:
    0
    Hiho,
    ich lese zurzeit ein Qt-Buch und wollte mal eine kleine Anwendung schreiben.
    Jetzt habe ich aber schon zu Beginn ein Problem.
    Mit folgendem Code im Konstruktor will ich das Layout des MainWindows bestimmen:
    Code:
    	QHBoxLayout *layout = new QHBoxLayout;
    	layout->addWidget(startNumberLabel);
    	layout->addWidget(startNumber);
    	layout->addWidget(endNumberLabel);
    	layout->addWidget(endNumber);
    	setLayout(layout);
    
    Zur Laufzeit tritt dann aber folgender Fehler auf:
    Code:
    QWidget::setLayout: Attempting to add QLayout "" to MainWindow "", which already has a layout
    
    Das Ganze passiert natürlich nicht, wenn ich die Methode setLayout nicht aufrufe. Hab ich was verpasst, haben Widgets standardmäßig schon ein Layout oder wieso funktioniert das nicht?
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 Herr Nilsson, 16.04.2008
    Herr Nilsson

    Herr Nilsson Eroberer

    Dabei seit:
    21.03.2008
    Beiträge:
    62
    Zustimmungen:
    0
    Ort:
    Dortmund
    Schau Dir mal die Beschreibungen der Konstruktoren an. Da gibt es nur zwei Möglichkeiten:
    1. Du steckst ein Layout in ein bereits vorhandenes. Hierzu verwendest Du entweder den zweiten Konstruktor alleine - oder den dritten und fügst das Layout einem anderem hinzu.
    2. Du erzeugst ein "top-level layout"; hierbei mußt Du den ersten gezeigten Konstruktor verwenden.
    Wenn Du keine Parameter angibst, wird der Compiler den dritten Konstruktor wählen, weil dieser alle Parameter mit Vorgabewerten belegt und daher zur Not auch ohne Parameter aufgerufen werden kann.

    Du brauchst aber den Konstruktor #1, z.B.:
    Code:
    topLayout = new QHBoxLayout(this, 0, 5, "topLayout");
    topLayout->addWidget(foobarLabel);
    //kein setLayout(layout);
    
    Zudem ist häufig ratsam, den GUI-Entwurf mit dem Programm designer durchzuführen. (Ist bei manchen Systemen nicht im Suchpfad.)

    Manche Details wird man zwar später von Hand machen, aber Vorlagen (Positionierung, Variablennamen der Widgets etc) lassen sich damit bequem erstellen.
     
  4. #3 Barade, 16.04.2008
    Zuletzt bearbeitet: 16.04.2008
    Barade

    Barade Kellerkind

    Dabei seit:
    14.12.2007
    Beiträge:
    24
    Zustimmungen:
    0
    Danke für die schnelle Antwort.
    Leider bin ich jetzt etwas verwirrt. Ich dachte eigentlich, dass ich die Version 4.3 von Qt verwenden würde und da sehen die Konstruktoren so aus: Klick mich.
    Deine beziehen sich ja auf Version 3.3, so wie ich das sehe.
    Mein Buch handelt ebenfalls von Qt 4.
    Entweder habe ich jetzt nicht richtig nachgesehen oder sie unterscheiden sich wirklich.
    edit: Zum Designer:
    Ja, mir geht es momentan auch darum es von Hand (Darunter eben auch die Verwendung von Layouts) zu lernen. Falls es mir mal eher um die Zeit und den Aufwand geht, werde ich sicher bei trivialeren Programmen auf den Designer zurückgreifen.
     
  5. #4 Herr Nilsson, 16.04.2008
    Herr Nilsson

    Herr Nilsson Eroberer

    Dabei seit:
    21.03.2008
    Beiträge:
    62
    Zustimmungen:
    0
    Ort:
    Dortmund
    Ach du meine Güte, da haben die von Trolltech beim Wechsel von 3.x auf 4.x wirklich mal ein paar Sachen mehr verändert. Ich werde das wohl mal über kurz oder lang installieren müssen.

    Aber ich wette, die Sache mit dem "top level-layout" wird sich nicht verändert haben. Versuche mal den Konstruktor Nr. 2:
    QHBoxLayout::QHBoxLayout ( QWidget * parent );

    Schreib' mal, ob's dann klappt.
     
  6. andy81

    andy81 von_suse_zu_arch_wechsler

    Dabei seit:
    30.03.2008
    Beiträge:
    72
    Zustimmungen:
    0
    So müsste es auch gehen:

    Code:
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(startNumberLabel);
    layout->addWidget(startNumber);
    layout->addWidget(endNumberLabel);
    layout->addWidget(endNumber);
    
    ZentralWidget = new QWidget;
    ZentralWidget->setLayout(layout);
    setCentralWidget(ZentralWidget);
    
    So mache es ich zumindest immer
     
  7. #6 Herr Nilsson, 16.04.2008
    Herr Nilsson

    Herr Nilsson Eroberer

    Dabei seit:
    21.03.2008
    Beiträge:
    62
    Zustimmungen:
    0
    Ort:
    Dortmund
    Auch nicht schlecht :) Das klappt dann aber vermutlich nur bei QMainWindow.

    (Komisch, bisher war Qt meistens "aufwärtskompatibel". Da kommt wohl noch eine Menge Arbeit auf mich zu, falls jemand mal ein paar Updates haben möchte :( )
     
  8. Barade

    Barade Kellerkind

    Dabei seit:
    14.12.2007
    Beiträge:
    24
    Zustimmungen:
    0
    Danke für die Hilfe.
    Also, ich brauche es auch für das MainWindow.
    Im Buch war es für ein QDialog oder sowas, weshalb es da wohl wahrscheinlich geht.
    Der zweite Konstruktor geht auch nicht (Wahrscheinlich wegen des MainWindows).
    Benötigt man dann immer ein zentrales Widget in MainWindows?
    Und wie sieht es mit der Speicherverwaltung aus?
    Wird das CentralWidget automatisch freigegeben, muss man sich darum kümmern?
     
  9. andy81

    andy81 von_suse_zu_arch_wechsler

    Dabei seit:
    30.03.2008
    Beiträge:
    72
    Zustimmungen:
    0
    Also ich habe jetzt in der Dokumentation (QT Assistent) nochmals nachgesehen. Dort ist eigentlich ziemlich genau beschrieben wie eine QMainWindow-Instanz aufgebaut ist:

    Auf deutsch: du mußt den Umweg über das CentralWidget gehen, da QMainWindow sein eigenes Layout mitbringt.

    Wenn du QDialog verwendest, wie es scheinbar in deinem Buch gemacht worden ist, müsste deine ursprüngliche Version mit der Benutzung von setLayout auch funktionieren.

    Um die Speicherverwaltung kümmert sich normalerweise QT. So werden untergeordnete Objekte automatisch gelöscht, wenn das übergeordnete Element gelöscht wird. Und alle Widgets und Layouts, die sich in einem Fenster befinden, sind ja nachkommen dieses Fensters. Das gilt allerdings nur für die QT-Klassen. Um selbst erstellte Klassen musst du dich schon selbst kümmern.
     
  10. #9 Herr Nilsson, 17.04.2008
    Zuletzt bearbeitet: 17.04.2008
    Herr Nilsson

    Herr Nilsson Eroberer

    Dabei seit:
    21.03.2008
    Beiträge:
    62
    Zustimmungen:
    0
    Ort:
    Dortmund
    Hier noch mal ein interessanter Link zu MainWindow inklusive eine Gegenüberstellung von Qt3 und Qt4.

    Zum Beispiel, indem Du sie zuerst von QObject ableitest und Deinem Objekt den Zeiger des Elternobjekts übergibst. Wird dann das Elternobjekt gelöscht, kann anhand des Objektbaums erkannt werden, daß das "Kindsobjekt" auch zu löschen ist.

    Früher galt die Einschränkung, daß man auf Objekte, die von QObject abgeleitet wurden, nicht mehrfachvererben kann. Wird wahrscheinlich auch noch für Qt 4 gelten.

    Falls Du es so machen willst, schau Dir auch mal diese Bemerkung zum Q_OBJECT-Makro an; dieses müßtest Du dann nämlich auch einbinden.
     
  11. rdg

    rdg ???

    Dabei seit:
    12.10.2006
    Beiträge:
    357
    Zustimmungen:
    0
    Ort:
    Berlin
    Hi,
    ich hab mal noch eine frage dazu,

    ich habe eine main
    eine layout klasse
    und die Klasse mit dem beenden button
    Wie bekomme ich es hin, das exitButton app zum beenden kennt?

    vielen dank im vorraus
    rdg
     
  12. andy81

    andy81 von_suse_zu_arch_wechsler

    Dabei seit:
    30.03.2008
    Beiträge:
    72
    Zustimmungen:
    0
    Ich bin mir nicht ganz sicher, ob ich dein Problem richtig verstanden habe, aber für mich sieht dein Aufbau etwas merkwürdig aus.

    Für was brauchst du z.B. die eigene Layoutklasse. Normalerweise wird das ja so gelöst, dass du ein Layout erzeugst (also QHBoxLayout, QVBoxLayout oder QGridLayout, je nachdem was du haben willst) und diesem Layout dann Widgets, also hier deine Buttons zuweist. Das ganze kannst du dann auch noch Verschachteln, so dass du ein Layout im Layout hast und somit alle möglichen Fensterlayouts erzeugen kannst.

    Das fertige Layout kannst du dann einem Widget zuweisen. Das kann wie weiter oben im Thread ein Zentrales Widget eines QMainWindow sein, oder auch direkt ein QDialog.

    Jetzt zum eigentlichen Problem:

    Wenn du es so machst wie ich gerade beschrieben habe hast du zwei Möglichkeiten dein Programm über einen Button zu beenden.

    1. Du machst es direkt in der main-Funktion, legst also deine ganzen Widgets und Layouts an und connectest direkt auf die Instanz der Applikation. Also ugefähr so:

    Code:
    int main(...)
    {
       [...]
       QWidget *window = new QWidget;
       QPushButton *button = new QPushButton("quit");
    
       QVBoxLayout *layout = new QVBoxLayout;
    
       layout->addWidget(button);
    
       window->setLayout(layout);
    
       QObject::connect(button, SIGNAL(clicked()), &app, SLOT(quit()));
       window->show();
       return app.exec();
    }
    
    2. Du hast ein etwas komplexeres Fenster, z.B einen QDialog. Dann erstellst du im Konstruktor die ganzen Widgets und gibst als Parent immer den this-Pointer an. Damit hast du erreicht, dass alle Objekte, also Buttons, Layouts etc. Kindobjekte des Fensters sind. Beim connecten kannst du dann einfach das Fenster schließen, wenn dein Button gedrückt wird. Wenn es das letzte Fenster war, wird die Anwendung automatisch geschlossen.
     
  13. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  14. #12 rdg, 04.05.2008
    Zuletzt bearbeitet: 04.05.2008
    rdg

    rdg ???

    Dabei seit:
    12.10.2006
    Beiträge:
    357
    Zustimmungen:
    0
    Ort:
    Berlin
    Ja aber weil der Qcode mir zu lang wird habe ich es in Klassen unterteilt um sie auch handhaberer zu machen.

    dank Dir vielmals mit dem this hast Du mich auf den richtigen Weg gebracht.

    vielen dank!!!
     
  15. #13 root1992, 16.06.2008
    root1992

    root1992 von IT-Lehrern besessen

    Dabei seit:
    02.01.2006
    Beiträge:
    1.138
    Zustimmungen:
    0
    Ort:
    Märchenwald
    Für den Anfang probier mal den Designer. Ich bin zwar kein Fan von IDE's aber wenn man schnell mal ne Form braucht ist es nicht schlecht.
    Designer zu Qt3:
    Ist bis auf paar bugs recht gut aber mir z.T. zu automatisch.
    Designer zu Qt4
    Benutze ihn nur für ne Form (.ui) und Quelltext per Kwrite

    BTW wenn du willst kann ich dir n Prog von mir mailen, das erstellt ein Programm aus einer Config und einer .ui (Kann man sogar interaktiv per shellskripte machen) evtl kannst du dir da paar Sachen abgucken. Schreib einfach ne mail oder pm (bzw wenn sich jmd andester dafür interessiert einfach melden)
     
Thema:

Qt - Layout

Die Seite wird geladen...

Qt - Layout - Ähnliche Themen

  1. gdm overwrites layout set with xrandr in xinit.rc

    gdm overwrites layout set with xrandr in xinit.rc: Hi I want to set xrandr --output VGA1 --left-of LVDS1 --mode 1680x1050 --primary. So i wrote this command into xinit.rc I launch...
  2. Artikel: 960-Grid-System - Eine CSS-Bibliothek für Spaltenlayouts

    Artikel: 960-Grid-System - Eine CSS-Bibliothek für Spaltenlayouts: Das Internet und dessen primär HTML-basierter Inhalt ist heute allgegenwärtig. Dem Einstellen von eigenen Inhalten stehen dabei keine...
  3. Tastatur mit englischem Layout

    Tastatur mit englischem Layout: Eigentlich gehört das Thema schon fast in den Off-Topic bereich. Also falls ein Moderator findet, dass es dorthin verschoben gehört... bitte :)...
  4. Forum Layout

    Forum Layout: Hallo, Es fehlt seit der Umstellung des Layouts der Link zum IRC-Channel. ich hätte folgendes anzubieten:...
  5. Ubuntu Server 9.04 - Tastaurlayout Probleme

    Ubuntu Server 9.04 - Tastaurlayout Probleme: Hallo, ich bin am verzweifeln, da jegliche Versuche bislang gescheitert sind. Ich fahre ein Umbuntu-Server-Image lokal über VMWare und habe...