Home | All Classes | Main Classes | Annotated | Grouped Classes | Functions |

# The Qt 4 Main Window Classes

Qt 4 introduces a new set of main window classes that will replace the Qt 3 main window classes, providing a more efficient implementation while remaining easy-to-use.

- Overview of the Main Window Classes
- The Current State of the Main Window Classes
- What's Changed Since Qt 4 Technology Preview 2?
- Example Code
- What's Changed since Qt 3?
- Future Work

## Overview of the Main Window Classes

The main window-related classes have been redesigned to satisfy a number of requirements, addressing issues raised by our customers and internal developers. The aim of this redesign is to provide a more consistent and efficient framework for main window management.

Tool bar and dock window functionality is provided by two independent classes: QToolBar and QDockWindow. Tool bars and dock windows reside in separate areas, with tool bars outside the dock window area. This behavior differs from the standard Qt 3 behavior, where QToolBar inherited functionality from QDockWindow, and both types of component shared the same areas. The result is a more consistent and predictable experience for users. Tool bars and dock windows provide feedback while being dragged into their new positions.

The diagram above shows the layout of a main window that contains both tool bars and dock windows. Each corner area can be used by either of the adjacent dock window areas, allowing dock window behavior and main window layout to be specified precisely.

Tool bars and dock windows are child widgets of the main window. They are no longer reparented into a dock area widget by the main window. Instead, layouts are used to manage the placement of tool bars and dock windows. One consequence is that the old QDockArea class is no longer required in Qt 4.

## The Current State of the Main Window Classes

Qt 4 provides the following classes for managing main windows and associated user interface components:

- QMainWindow remains the central class around which applications can be built. The interface to this class has been simplified -- much of the functionality previously included is now present in the companion classes, QDockWindow and QToolBar.
- QDockWindow provides a widget that can be used to create detachable tool palettes or helper windows. Dock windows keep track of their own properties -- they can be moved, closed, and floated as external windows.
- QToolBar provides a generic tool bar widget that can hold a number of different action-related widgets, such as buttons, drop-down menus, comboboxes, and spin boxes. The emphasis on a unified action model in Qt 4 means that tool bars cooperate well with menus and keyboard shortcuts.

## What's Changed Since Qt 4 Technology Preview 2?

- The tool bar and dock window context menu has been added.
- Saving and restoring of dock window and tool bar states is now implemented.
- Support for large pixmaps and text labels in tool bar buttons has been added.
- Support for arbitrary widgets in the tool bar is now present.
- The previously private button class `QToolBarButton` that was used by `addAction()` and `insertAction()` has been merged with QToolButton.

## Example Code

Using QMainWindow is straightforward. Generally, we subclass QMainWindow and set up menus, tool bars, and dock windows inside the QMainWindow constructor.

To add a menu bar to the main window, we simply create the menus, and add them to the main window's menu bar. Note that the QMainWindow::menuBar() function will automatically create the menu bar the first time it is called. You can also call QMainWindow::setMenuBar() to use a custom menu bar in the main window.

        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent)
        {
            ...
            QAction *newAction = new QAction(tr("&New"), this);
            QAction *openAction = new QAction(tr("&Open"), this);
            ...

Once actions have been created, we can add them to the main window components. To begin with, we add them to the popup menus:

            QMenu *fileMenu = new QMenu(tr("&File"), this);
            QMenu *editMenu = new QMenu(tr("&Edit"), this);
            QMenu *helpMenu = new QMenu(tr("&Help"), this);
            ...
            fileMenu->addAction(newAction);
            fileMenu->addAction(openAction);
            fileMenu->addAction(saveAction);
            fileMenu->addAction(saveAsAction);
            fileMenu->addSeparator();
            ...
            menuBar()->addMenu(fileMenu);
            menuBar()->addMenu(editMenu);
            menuBar()->addMenu(helpMenu);
            ...
        }

The QToolBar and QMenu classes use Qt's action system to provide a consistent API. In the above code, some existing actions were added to the file menu with the QMenu::addAction() function. QToolBar also provides this function, making it easy to reuse actions in different parts of the main window. This avoids unnecessary duplication of work.

We create a tool bar as a child of the main window, and add the desired actions to it:

        QToolBar *toolbar = new QToolBar(this);
        toolbar->setWindowTitle(tr("Main Tool Bar"));

        toolbar->addAction(openAction);
        toolbar->addAction(saveAction);
        toolbar->addAction(printAction);
        toolbar->addSeparator();
        toolbar->addAction(undoAction);
        toolbar->addAction(redoAction);
        ...
        toolbar->setAllowedAreas(Qt::ToolBarAreaTop | Qt::ToolBarAreaBottom);
        toolbar->setArea(Qt::ToolBarAreaTop);

In this example, the tool bar is restricted to the top and bottom tool bar areas of the main window, and is initially placed in the top tool bar area. We can see that the actions specified by `openAction` and `saveAction` will be displayed both on the tool bar and in the file menu.

QDockWindow is used in a similar way to QToolBar. We create a dock window as a child of the main window, and add widgets as children of the dock window:

        QDockWindow *dockWindow = new QDockWindow(mainWindow);
        dockwindow->setWindowTitle(tr("Tools"));

        QWidget *widget = new QWidget(dockwindow);
        ...
        dockwindow->setAllowedArea(Qt::DockWindowAreaLeft | Qt::DockWindowAreaRight);
        mainWindow->addDockWindow(Qt::DockWindowAreaLeft, dockWindow);

In this example, the dock window can only be placed in the left and right dock areas, and it is initially placed in the left dock area.

The QMainWindow API allows the programmer to customize which dock window areas occupy the four corners of the dock window area. If required, the default can be changed with the QMainWindow::setCorner() function:

        setCorner(Qt::TopLeftCorner, Qt::DockWindowAreaLeft);
        setCorner(Qt::BottomLeftCorner, Qt::DockWindowAreaLeft);
        setCorner(Qt::TopRightCorner, Qt::DockWindowAreaRight);
        setCorner(Qt::BottomRightCorner, Qt::DockWindowAreaRight);

The following diagram shows the configuration produced by the above code. Note that the left and right dock windows will occupy the top and bottom corners of the main window in this layout.

Finally, once all of the main window components have been set up, the central widget is created and installed:

        QWidget *centralWidget = new QWidget(this);
        setCentralWidget(centralWidget);

The central widget can be any subclass of QWidget.

## What's Changed since Qt 3?

Although the QMainWindow class in Qt 3 provided support for tool bars, dock windows, and other standard user interface components, its design meant that these items were managed through a large number of QMainWindow member functions. In Qt 4, the QMainWindow class delegates many of the management tasks to QDockWindow and QToolBar. As a result, these classes are used in a slightly different way in Qt 4.

QMainWindow retains the menuBar() function, but menus are always constructed using QAction objects. All kinds of menus are constructed using the general QMenu class.

Qt 3:

        QPopupMenu *fileMenu = new QPopupMenu(this);
        ...
        openAction->addTo(fileMenu);
        ...
        menuBar()->insertItem(tr("&File"), fileMenu);

Qt 4:

        QMenu *fileMenu = new QMenu(this);
        ...
        fileMenu->addAction(openAction);
        ...
        menuBar()->addMenu(tr("&File"), fileMenu);

Tool bars follow the same pattern as menus, with the new, more consistent behavior:

Qt 3:

        QToolBar *fileTools = new QToolBar(this, "file tool bar");
        ...
        openAction->addTo(fileTools);

Qt 4:

        QToolBar *fileTools = new QToolBar(this);
        fileTools->setWindowTitle(tr("File Tool Bar"));
        ...
        fileTools->addAction(openAction);

The behavior of dock windows is now configured through the member functions of QDockWindow. For example, compare the old and new ways of creating a dock window in the dock area on the left hand side of the main window.

In Qt 3:

        QDockWindow *dockWindow = new QDockWindow(this);
        mainWin->moveDockWindow(dockWindow, Qt::DockLeft);

In Qt 4:

        QDockWindow *dockWindow = new QDockWindow(mainWindow);
        mainWindow->addDockWindow(Qt::DockWindowAreaLeft, dockWindow);

These changes provide more than a cosmetic improvement to Qt's API. They allow more consistent behavior to be defined and implemented. In response to feedback from customers, we hope to improve these classes even further.

## Future Work

The main window classes will continue to evolve and improve as part of the push toward Qt 4. Below are some ideas that have been discussed by the Trolltech development team, and put forward for implementation. Feedback is welcome and encouraged.

- Dragging/dropping behavior may change such that dropped dock windows will always split a single dock window. (The current behavior when placing a dock window between two other dock windows is to take equal space from each to make room for the newly placed dock window.)
- When unfloating a dock window, the main window could remember the original location such that, if the user clicks the "unfloat" button, the dockwindow would return to the original location. (The current behavior is to re-insert the dock window at the end of the layout.)

[Back to the Beta page]