Home · All Classes · Main Classes · Annotated · Grouped Classes · Functions

Basic Layouts Example

Files:

The Basic layout example shows how to use the standard layout managers that are available in Qt: QBoxLayout and QGridLayout.

Screenshot of the Basic Layouts example

The QBoxLayout class lines up widgets horizontally or vertically. QHBoxLayout and QVBoxLayout are convenience classes corresponding to the layout's orientation. They inherit QBoxLayout, and are the easiest way to use QBoxLayout.

Dialog Class Definition

    class Dialog : public QWidget
    {
        Q_OBJECT

    public:
        Dialog();

    private:
        void createMenu();
        void createHorizontalGroupBox();
        void createGridGroupBox();

        enum { NumGridRows = 3, NumButtons = 4 };

        QMenuBar *menuBar;
        QGroupBox *horizontalGroupBox;
        QGroupBox *gridGroupBox;
        QTextEdit *smallEditor;
        QTextEdit *bigEditor;
        QLabel *labels[NumGridRows];
        QLineEdit *lineEdits[NumGridRows];
        QPushButton *buttons[NumButtons];
        QPushButton *okButton;
        QPushButton *cancelButton;

        QMenu *fileMenu;
        QAction *exitAction;
    };

The Dialog class inherits QWidget. It is a custom widget that displays its child widgets using the geometry managers: QHBoxLayout, OVBoxLayout and QGridLayout.

We create three private functions to simplify the class constructor:

The createMenu() function creates and populates a menu bar. The createHorizontalGroupBox() function creates a group box containing four buttons managed by a horizontal layout, and createGridGroupBox() creates a group box containing three line edits and a small editor managed by a grid layout.

Dialog Class Implementation

    Dialog::Dialog()
    {
        createMenu();
        createHorizontalGroupBox();
        createGridGroupBox();

        bigEditor = new QTextEdit;
        bigEditor->setPlainText(tr("This widget takes up all the remaining space "
                                   "in the top-level layout."));

        okButton = new QPushButton(tr("OK"));
        cancelButton = new QPushButton(tr("Cancel"));
        okButton->setDefault(true);

        connect(okButton, SIGNAL(clicked()), this, SLOT(close()));
        connect(cancelButton, SIGNAL(clicked()), this, SLOT(close()));

        QHBoxLayout *buttonLayout = new QHBoxLayout;
        buttonLayout->addStretch(1);
        buttonLayout->addWidget(okButton);
        buttonLayout->addWidget(cancelButton);

In the constructor, we create several widgets that the example uses to demonstrate how the layout affect their appearances. Some of them are grouped together and given their own internal layouts.

        QVBoxLayout *mainLayout = new QVBoxLayout;

The main layout for the Dialog widget is a QVBoxLayout.

The QBoxLayout class takes in general the space it gets (from its parent layout or from the parent widget), divides it up into a series of boxes, and makes each managed widget fill one box. If the QBoxLayout's orientation is Qt::Horizontal the boxes are placed in a row. If the orientation is Qt::Vertical, the boxes are placed in a column. The corresponding convenience classes are QHBoxLayout and QVBoxLayout, respectively.

        mainLayout->setMenuBar(menuBar);

When we call the QLayout::setMenubar() function, the layout places the provided menu bar at the top of the parent widget, and outside the widgets content margins. All child widgets are placed below the bottom edge of the menu bar.

        mainLayout->addWidget(horizontalGroupBox);
        mainLayout->addWidget(gridGroupBox);
        mainLayout->addWidget(bigEditor);
        mainLayout->addLayout(buttonLayout);
        setLayout(mainLayout);

        setWindowTitle(tr("Basic Layouts"));
    }

We use the QBoxLayout::addWidget() function to add the widgets to the end of the main layout. Each widget will get at least its minimum size and at most its maximum size. It is possible to specify a stretch factor in the addWidget() function, and any excess space is shared according to these stretch factors. If it's not specified, a widget's stretch factor is 0 by default.

In the same way, we can use QBoxLayout::addLayout() to add another layout, and its widgets, to the end of the main layout. Again it is possible to specify a stretch factor which, if not specified, is 0 by default.

Then, when we call QWidget::setLayout() to install the main layout on the Dialog widget, we automatically reparent all of the layout's widgets to be children of the Dialog widget.

    void Dialog::createMenu()
    {
        menuBar = new QMenuBar;

        fileMenu = new QMenu(tr("&File"), this);
        exitAction = fileMenu->addAction(tr("E&xit"));
        menuBar->addMenu(fileMenu);

        connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
    }

In the private createMenu() function we create a horizontal menu bar, and add a pull down File menu containing an Exit option.

    void Dialog::createHorizontalGroupBox()
    {
        horizontalGroupBox = new QGroupBox(tr("Horizontal layout"));
        QHBoxLayout *layout = new QHBoxLayout;

        for (int i = 0; i < NumButtons; ++i) {
            buttons[i] = new QPushButton(tr("Button %1").arg(i + 1));
            layout->addWidget(buttons[i]);
        }
        horizontalGroupBox->setLayout(layout);
    }

When we create the horizontal group box, we use a QHBoxLayout as the internal layout. We create the buttons we want to put in the group box, add them to the layout and install the layout on the group box.

    void Dialog::createGridGroupBox()
    {
        gridGroupBox = new QGroupBox(tr("Grid layout"));

In the createGridGroupBox() function we use a QGridLayout which lays out widgets in a grid. It takes the space made available to it (by its parent layout or by the parent widget), divides it up into rows and columns, and puts each widget it manages into the correct cell.

        for (int i = 0; i < NumGridRows; ++i) {
            labels[i] = new QLabel(tr("Line %1:").arg(i + 1));
            lineEdits[i] = new QLineEdit;
            layout->addWidget(labels[i], i, 0);
            layout->addWidget(lineEdits[i], i, 1);
        }

For each row in the grid we create a label and an associated line edit, and add them to the layout. The QGridLayout::addWidget() function differ from the corresponding function in QBoxLayout: It needs the row and column specifying the grid cell to put the widget in.

        smallEditor = new QTextEdit;
        smallEditor->setPlainText(tr("This widget takes up about two thirds of the "
                                     "grid layout."));
        layout->addWidget(smallEditor, 0, 2, 3, 1);

QGridlayout::addWidget() can in addition take arguments specifying the number of rows and columns the cell will be spanning. In this example, we create a small editor which we span over three rows and one column.

For both the QBoxLayout::addWidget() and QGridLayout::addWidget() functions it is also possible to add a last argument specifying the widget's alignment. By default it fills the whole cell. But we could, for example, align a widget with the right edge by specifying the alignment to be Qt::AlignRight.

        layout->setColumnStretch(1, 10);
        layout->setColumnStretch(2, 20);
        gridGroupBox->setLayout(layout);
    }

Each column in a grid layout has a stretch factor. The stretch factor is set using QGridLayout::setColumnStretch() and determines how much of the available space the column will get over and above its necessary minimum. If not specified, the stretch factor is 0 by default.

Columns and rows behave identically; there is an equivalent stretch factor for rows, as well as a QGridLayout::setRowStretch() function.

In this example, we set the stretch factors for the second and third column (the first column is number 0). The stretch factor is relative to the other columns in this grid; columns with a higher stretch factor take more of the available space. So the third column in our grid layout will get more of the available space than the second, and the first column will not grow at all since its stretch factor has not been explicitly set and is 0 by default.


Copyright © 2005 Trolltech Trademarks
Qt 4.0.0-rc1