====== Horizontale und vertikale Layouts ====== Bei diesen beiden Formen von Layouts werden die Widgets von links nach rechts bzw. von oben nach unten angeordnet.\\ Dazu werden die Layout-Klassen ''QHBoxLayout'' (horizontal) und ''QVBoxLayout'' (vertikal) verwendet. Widgets werden mit der Funktion ''addWidget()'' hinzugefügt. Diese Funktion ist bereits in der Basisklasse ''QBoxLayout'' implementiert und wird in den Basisklassen entsprechend der Auslegungsrichtung angepasst: void QBoxLayout::addWidget( QWidget *widget, int stretch = 0, Qt::Alignment alignment = Qt::Alignment() ) **widget**: Das einzufügende Widget \\ **stretch**: Gibt an, wie sich das Widget bei Vergrößerung des verfügbaren Raumes vergrößert \\ **alignment**: Gibt die Ausrichtung des Widgets an (wird von ''QHBoxLayout'' bzw. ''QVBoxLayout'' automatisch angepasst) \\ \\ Analog dazu werden Layouts mit der Methode ''addLayout()'' hinzugefügt: \\ void QBoxLayout::addLayout( QLayout *layout, int stretch = 0 ) **layout**: Das einzufügende Layout \\ **stretch**: Gibt an, wie sich das Layout bei Vergrößerung des verfügbaren Raumes vergrößert \\ Nun wollen wir unser Beispiel zur Synchronisierung von Widgets aus dem [[frameworks:qt:basic:connections|vorherigen Kapitel]] mit Layouts in einem Widget zusammenfassen: #include #include #include #include #include #include int main( int argc, char *argv[] ) { QApplication app( argc, argv ); QSpinBox *spinbox; QSlider *slider; QPushButton *button; QHBoxLayout *hlayout; QVBoxLayout *vlayout; QWidget widget; // Objekte anlegen spinbox = new QSpinBox(); slider = new QSlider(); button = new QPushButton( "Quit" ); hlayout = new QHBoxLayout(); vlayout = new QVBoxLayout(); // Wertebereich für Spinbox setzen spinbox->setMinimum( 0 ); spinbox->setMaximum( 100 ); // Wertebereich für Slider setzen slider->setMinimum( 0 ); slider->setMaximum( 100 ); // Slider quer darstellen slider->setOrientation( Qt::Horizontal ); // Verbindungen erstellen QObject::connect( spinbox, static_cast( &QSpinBox::valueChanged ), slider, &QSlider::setValue ); QObject::connect( slider, static_cast( &QSlider::valueChanged ), spinbox, &QSpinBox::setValue ); QObject::connect( button, &QPushButton::clicked, &app, &QApplication::quit ); // Button und Spinbox zusammen in ein vertikales Layout einfügen vlayout->addWidget( slider ); vlayout->addWidget( spinbox ); // Vertikales Layout und Button in ein horizontales Layout einfügen hlayout->addLayout( vlayout ); hlayout->addWidget( button ); // Layout auf das Widget anwenden und Widget anzeigen widget.setWindowTitle( "Layouts" ); widget.setLayout( hlayout ); widget.show(); return app.exec(); } Im Beispiel erstellen wir uns das Hilfswidget ''widget'', dessen einziger Zweck es ist das Layout anzunehmen und die anderen Widgets anzuzeigen. Durch die Verwendung von Layouts wird es zum Elternwidget aller anderen Widgets, die sich im angewandten Layout befinden (''slider'', ''spinbox'' und ''button''). Für die Widgets werden in diesem Beispiel Zeiger verwendet. Der Grund dafür ist einfach: Wie wir bereits gehört haben, übernimmt das Hauptwidget die Elternschaft über die Widgets in den Layouts. Wird das Hauptwidget zerstört (Aufruf des Destruktors nach ''main''), versucht es den Speicher der Kindwidgets freizugeben. Verwenden wir dann für Widgets keine Zeiger, wird der Speicher der bereits zerstörten Widgets freigegeben. Deshalb sollte man für Widgets, die ein Elternobjekt bekommen, immer Zeiger verwenden. Aufgrund dieser Eigenschaft führt unser Programm auch nicht zu einem Speicherleck. Hier ein Bild der Anwendung wobei die Verschachtelung der Layouts besonders hervorgehoben wurde (rot = vertikales Layout, grün = horizontales Layout): \\ {{:frameworks:qt:gui:basic:layouts:layouts1.png}}