Archived:Implementing a layout manager in Qt

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngArchived: This article is archived because it is not considered relevant for third-party developers creating commercial solutions today. If you think this article is still relevant, let us know by adding the template {{ReviewForRemovalFromArchive|user=~~~~|write your reason here}}.

Qt Quick should be used for all UI development on mobile devices. The approach described in this article (using C++ for the Qt app UI) is deprecated.

This code example shows how to create a custom layout manager Qt. A flow layout is used as an example layout.

Article Metadata
Code Example
Source file: Media:LMExample.zip
Tested with
Devices(s): 5800 XpressMusic
Platform(s): Qt
S60 5th Edition
Keywords: layout manager, QLayout
Created: taaidant (17 Feb 2009)
Last edited: hamishwillee (17 Oct 2012)



After you have subclassed the QLayout and implemented the needed methods, the layout works for any other QLayout.

Setup code in QMainWindow

QWidget* centralWidget = new QWidget;
FlowLayout* mainLayout = new FlowLayout;

Adding widgets

QTextEdit* editor = new QTextEdit;
QPushButton* button = new QPushButton("Push me!");
QPushButton* button2 = new QPushButton("Push me too!");
QPushButton* button3 = new QPushButton("No! Not them... Push me!");

Header file

* Copyright (c) 2009 Nokia Corporation
* Original example taken from:
* http://doc.trolltech.com/4.4/layouts-flowlayout.html

#include <QLayout>
#include <QRect>
#include <QWidgetItem>
class FlowLayout : public QLayout
FlowLayout(QWidget *parent, int margin = 0, int spacing = -1);
FlowLayout(int spacing = -1);

Public members

Here are some basic methods you have to implement. Explanations to all of these methods can be found in the Qt documentation.

Item manipulation

     /* http://doc.trolltech.com/qlayout.html#addItem */
void addItem(QLayoutItem *item);
/* http://doc.trolltech.com/qlayout.html#count */
int count() const;
/* http://doc.trolltech.com/qlayout.html#itemAt */
QLayoutItem *itemAt(int index) const;
/* http://doc.trolltech.com/qlayout.html#takeAt */
QLayoutItem *takeAt(int index);

Layout and item geometry features

     /* http://doc.trolltech.com/qlayout.html#expandingDirections */
Qt::Orientations expandingDirections() const;
/* http://doc.trolltech.com/qlayoutitem.html#hasHeightForWidth */
bool hasHeightForWidth() const;
/* http://doc.trolltech.com/qlayoutitem.html#heightForWidth */
int heightForWidth(int) const;
/* http://doc.trolltech.com/qlayout.html#minimumSize */
QSize minimumSize() const;
/* http://doc.trolltech.com/qlayoutitem.html#setGeometry */
void setGeometry(const QRect &rect);
/* http://doc.trolltech.com/qlayoutitem.html#sizeHint */
QSize sizeHint() const;

Private members

* Calculates the positions and sizes of the widgets in the layout,
* sets them and returns the height of the layout.

int doLayout(const QRect &rect, bool testOnly) const;
/* Contains the items in this layout. */
QList<QLayoutItem *> itemList;

Source file

* Copyright (c) 2009 Nokia Corporation
* Original example taken from:
* http://doc.trolltech.com/4.4/layouts-flowlayout.html

#include <QtGui>
#include "flowlayout.h"
FlowLayout::FlowLayout(QWidget *parent, int margin, int spacing)
: QLayout(parent)
FlowLayout::FlowLayout(int spacing)
QLayoutItem *item;
while ((item = takeAt(0)))
delete item;

Public members

Item manipulation

/* Adds an item to end of the itemList */
void FlowLayout::addItem(QLayoutItem *item)
/* Returns the amount of items layout contains. */
int FlowLayout::count() const
return itemList.size();
/* Returns item pointer for the given index. */
QLayoutItem *FlowLayout::itemAt(int index) const
return itemList.value(index);
/* Takes and returns the item from the given index of the itemList */
QLayoutItem *FlowLayout::takeAt(int index)
if (index >= 0 && index < itemList.size())
return itemList.takeAt(index);
return 0;

Layout and item geometry features

/* Would tell which way the layout expands if it were implemented. */
Qt::Orientations FlowLayout::expandingDirections() const
return 0;
/* Tells if the layout handles width to height calculations. */
bool FlowLayout::hasHeightForWidth() const
return true;
/* Calculates height from width. */
int FlowLayout::heightForWidth(int width) const
int height = doLayout(QRect(0, 0, width, 0), true);
return height;
/* Sets the layouts geometry. */
void FlowLayout::setGeometry(const QRect &rect)
doLayout(rect, false);
/* Returns the layouts preferred size. */
QSize FlowLayout::sizeHint() const
return minimumSize();
* Returns the minimum size of the layout.
* First find the the biggest minimum size and add margin to that.

QSize FlowLayout::minimumSize() const
QSize size;
QLayoutItem *item;
foreach (item, itemList)
size = size.expandedTo(item->minimumSize());
size += QSize(2*margin(), 2*margin());
return size;

Private members

Geometry calculations

Here the layout does all the "hard work". It calculates the layout and returns the height.

int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
int x = rect.x();
int y = rect.y();
int lineHeight = 0;
QLayoutItem *item;
/* For every element in itemList */
foreach (item, itemList) {
/* Next x is the items sizeHint's width + spacing */
int nextX = x + item->sizeHint().width() + spacing();
* If the next x - spacing is greater than rect's right coordinate and
* line height is greater than zero, start a new line.

if (nextX - spacing() > rect.right() && lineHeight > 0) {
x = rect.x();
y = y + lineHeight + spacing();
nextX = x + item->sizeHint().width() + spacing();
lineHeight = 0;
/* Set the geometry for current widget. */
if (!testOnly)
item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
/* Prepare for the next item. */
x = nextX;
lineHeight = qMax(lineHeight, item->sizeHint().height());
/* Returns height for the layout. */
return y + lineHeight - rect.y();


You know the basics of implementing a layout manager.

Supplementary material

  • You can test the FlowLayout manager with a test application. The application is available for download at File:LMExample.zip.

See also

This page was last modified on 17 October 2012, at 09:15.
101 page views in the last 30 days.