C++/Qt/QLayout
extends QLayout to create border layout
<source lang="cpp"> /****************************************************************************
- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- All rights reserved.
- Contact: Nokia Corporation (qt-info@nokia.com)
- This file is part of the examples of the Qt Toolkit.
- $QT_BEGIN_LICENSE:LGPL$
- Commercial Usage
- Licensees holding valid Qt Commercial licenses may use this file in
- accordance with the Qt Commercial License Agreement provided with the
- Software or, alternatively, in accordance with the terms contained in
- a written agreement between you and Nokia.
- GNU Lesser General Public License Usage
- Alternatively, this file may be used under the terms of the GNU Lesser
- General Public License version 2.1 as published by the Free Software
- Foundation and appearing in the file LICENSE.LGPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU Lesser General Public License version 2.1 requirements
- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- In addition, as a special exception, Nokia gives you certain additional
- rights. These rights are described in the Nokia Qt LGPL Exception
- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- GNU General Public License Usage
- Alternatively, this file may be used under the terms of the GNU
- General Public License version 3.0 as published by the Free Software
- Foundation and appearing in the file LICENSE.GPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU General Public License version 3.0 requirements will be
- met: http://www.gnu.org/copyleft/gpl.html.
- If you have questions regarding the use of this file, please contact
- Nokia at qt-info@nokia.com.
- $QT_END_LICENSE$
-
- /
- ifndef BORDERLAYOUT_H
- define BORDERLAYOUT_H
- include <QLayout>
- include <QRect>
- include <QWidgetItem>
class BorderLayout : public QLayout { public:
enum Position { West, North, South, East, Center }; BorderLayout(QWidget *parent, int margin = 0, int spacing = -1); BorderLayout(int spacing = -1); ~BorderLayout(); void addItem(QLayoutItem *item); void addWidget(QWidget *widget, Position position); Qt::Orientations expandingDirections() const; bool hasHeightForWidth() const; int count() const; QLayoutItem *itemAt(int index) const; QSize minimumSize() const; void setGeometry(const QRect &rect); QSize sizeHint() const; QLayoutItem *takeAt(int index); void add(QLayoutItem *item, Position position);
private:
struct ItemWrapper { ItemWrapper(QLayoutItem *i, Position p) { item = i; position = p; } QLayoutItem *item; Position position; }; enum SizeType { MinimumSize, SizeHint }; QSize calculateSize(SizeType sizeType) const; QList<ItemWrapper *> list;
};
- endif
- include <QtGui>
- include "borderlayout.h"
BorderLayout::BorderLayout(QWidget *parent, int margin, int spacing)
: QLayout(parent)
{
setMargin(margin); setSpacing(spacing);
} BorderLayout::BorderLayout(int spacing) {
setSpacing(spacing);
}
BorderLayout::~BorderLayout() {
QLayoutItem *l; while ((l = takeAt(0))) delete l;
} void BorderLayout::addItem(QLayoutItem *item) {
add(item, West);
} void BorderLayout::addWidget(QWidget *widget, Position position) {
add(new QWidgetItem(widget), position);
} Qt::Orientations BorderLayout::expandingDirections() const {
return Qt::Horizontal | Qt::Vertical;
} bool BorderLayout::hasHeightForWidth() const {
return false;
} int BorderLayout::count() const {
return list.size();
} QLayoutItem *BorderLayout::itemAt(int index) const {
ItemWrapper *wrapper = list.value(index); if (wrapper) return wrapper->item; else return 0;
} QSize BorderLayout::minimumSize() const {
return calculateSize(MinimumSize);
} void BorderLayout::setGeometry(const QRect &rect) {
ItemWrapper *center = 0; int eastWidth = 0; int westWidth = 0; int northHeight = 0; int southHeight = 0; int centerHeight = 0; int i; QLayout::setGeometry(rect); for (i = 0; i < list.size(); ++i) { ItemWrapper *wrapper = list.at(i); QLayoutItem *item = wrapper->item; Position position = wrapper->position; if (position == North) { item->setGeometry(QRect(rect.x(), northHeight, rect.width(), item->sizeHint().height())); northHeight += item->geometry().height() + spacing(); } else if (position == South) { item->setGeometry(QRect(item->geometry().x(), item->geometry().y(), rect.width(), item->sizeHint().height())); southHeight += item->geometry().height() + spacing(); item->setGeometry(QRect(rect.x(), rect.y() + rect.height() - southHeight + spacing(), item->geometry().width(), item->geometry().height())); } else if (position == Center) { center = wrapper; } } centerHeight = rect.height() - northHeight - southHeight; for (i = 0; i < list.size(); ++i) { ItemWrapper *wrapper = list.at(i); QLayoutItem *item = wrapper->item; Position position = wrapper->position; if (position == West) { item->setGeometry(QRect(rect.x() + westWidth, northHeight, item->sizeHint().width(), centerHeight)); westWidth += item->geometry().width() + spacing(); } else if (position == East) { item->setGeometry(QRect(item->geometry().x(), item->geometry().y(), item->sizeHint().width(), centerHeight)); eastWidth += item->geometry().width() + spacing(); item->setGeometry(QRect( rect.x() + rect.width() - eastWidth + spacing(), northHeight, item->geometry().width(), item->geometry().height())); } } if (center) center->item->setGeometry(QRect(westWidth, northHeight, rect.width() - eastWidth - westWidth, centerHeight));
} QSize BorderLayout::sizeHint() const {
return calculateSize(SizeHint);
} QLayoutItem *BorderLayout::takeAt(int index) {
if (index >= 0 && index < list.size()) { ItemWrapper *layoutStruct = list.takeAt(index); return layoutStruct->item; } return 0;
} void BorderLayout::add(QLayoutItem *item, Position position) {
list.append(new ItemWrapper(item, position));
} QSize BorderLayout::calculateSize(SizeType sizeType) const {
QSize totalSize; for (int i = 0; i < list.size(); ++i) { ItemWrapper *wrapper = list.at(i); Position position = wrapper->position; QSize itemSize; if (sizeType == MinimumSize) itemSize = wrapper->item->minimumSize(); else // (sizeType == SizeHint) itemSize = wrapper->item->sizeHint(); if (position == North || position == South || position == Center) totalSize.rheight() += itemSize.height(); if (position == West || position == East || position == Center) totalSize.rwidth() += itemSize.width(); } return totalSize;
}
- ifndef WINDOW_H
- define WINDOW_H
- include <QWidget>
QT_BEGIN_NAMESPACE class QLabel; QT_END_NAMESPACE class Window : public QWidget {
Q_OBJECT
public:
Window();
private:
QLabel *createLabel(const QString &text);
};
- endif
- include <QtGui>
- include "borderlayout.h"
- include "window.h"
Window::Window() {
QTextBrowser *centralWidget = new QTextBrowser; centralWidget->setPlainText(tr("Central widget")); BorderLayout *layout = new BorderLayout; layout->addWidget(centralWidget, BorderLayout::Center); layout->addWidget(createLabel("North"), BorderLayout::North); layout->addWidget(createLabel("West"), BorderLayout::West); layout->addWidget(createLabel("East 1"), BorderLayout::East); layout->addWidget(createLabel("East 2") , BorderLayout::East); layout->addWidget(createLabel("South"), BorderLayout::South); setLayout(layout); setWindowTitle(tr("Border Layout"));
} QLabel *Window::createLabel(const QString &text) {
QLabel *label = new QLabel(text); label->setFrameStyle(QFrame::Box | QFrame::Raised); return label;
}
- include <QApplication>
- include "window.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv); Window window; window.show(); return app.exec();
}
</source>
extends QLayout to create flow layout
<source lang="cpp"> /****************************************************************************
- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- All rights reserved.
- Contact: Nokia Corporation (qt-info@nokia.com)
- This file is part of the examples of the Qt Toolkit.
- $QT_BEGIN_LICENSE:LGPL$
- Commercial Usage
- Licensees holding valid Qt Commercial licenses may use this file in
- accordance with the Qt Commercial License Agreement provided with the
- Software or, alternatively, in accordance with the terms contained in
- a written agreement between you and Nokia.
- GNU Lesser General Public License Usage
- Alternatively, this file may be used under the terms of the GNU Lesser
- General Public License version 2.1 as published by the Free Software
- Foundation and appearing in the file LICENSE.LGPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU Lesser General Public License version 2.1 requirements
- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- In addition, as a special exception, Nokia gives you certain additional
- rights. These rights are described in the Nokia Qt LGPL Exception
- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- GNU General Public License Usage
- Alternatively, this file may be used under the terms of the GNU
- General Public License version 3.0 as published by the Free Software
- Foundation and appearing in the file LICENSE.GPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU General Public License version 3.0 requirements will be
- met: http://www.gnu.org/copyleft/gpl.html.
- If you have questions regarding the use of this file, please contact
- Nokia at qt-info@nokia.com.
- $QT_END_LICENSE$
-
- /
- ifndef FLOWLAYOUT_H
- define FLOWLAYOUT_H
- include <QLayout>
- include <QRect>
- include <QWidgetItem>
class FlowLayout : public QLayout { public:
FlowLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1); ~FlowLayout(); void addItem(QLayoutItem *item); int horizontalSpacing() const; int verticalSpacing() const; Qt::Orientations expandingDirections() const; bool hasHeightForWidth() const; int heightForWidth(int) const; int count() const; QLayoutItem *itemAt(int index) const; QSize minimumSize() const; void setGeometry(const QRect &rect); QSize sizeHint() const; QLayoutItem *takeAt(int index);
private:
int doLayout(const QRect &rect, bool testOnly) const; int smartSpacing(QStyle::PixelMetric pm) const; QList<QLayoutItem *> itemList; int m_hSpace; int m_vSpace;
};
- endif
- include <QtGui>
- include "flowlayout.h"
FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
} FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
: m_hSpace(hSpacing), m_vSpace(vSpacing)
{
setContentsMargins(margin, margin, margin, margin);
}
FlowLayout::~FlowLayout() {
QLayoutItem *item; while ((item = takeAt(0))) delete item;
}
void FlowLayout::addItem(QLayoutItem *item) {
itemList.append(item);
}
int FlowLayout::horizontalSpacing() const {
if (m_hSpace >= 0) { return m_hSpace; } else { return smartSpacing(QStyle::PM_LayoutHorizontalSpacing); }
} int FlowLayout::verticalSpacing() const {
if (m_vSpace >= 0) { return m_vSpace; } else { return smartSpacing(QStyle::PM_LayoutVerticalSpacing); }
}
int FlowLayout::count() const {
return itemList.size();
} QLayoutItem *FlowLayout::itemAt(int index) const {
return itemList.value(index);
} QLayoutItem *FlowLayout::takeAt(int index) {
if (index >= 0 && index < itemList.size()) return itemList.takeAt(index); else return 0;
}
Qt::Orientations FlowLayout::expandingDirections() const {
return 0;
}
bool FlowLayout::hasHeightForWidth() const {
return true;
} int FlowLayout::heightForWidth(int width) const {
int height = doLayout(QRect(0, 0, width, 0), true); return height;
}
void FlowLayout::setGeometry(const QRect &rect) {
QLayout::setGeometry(rect); doLayout(rect, false);
} QSize FlowLayout::sizeHint() const {
return minimumSize();
} QSize FlowLayout::minimumSize() const {
QSize size; QLayoutItem *item; foreach (item, itemList) size = size.expandedTo(item->minimumSize()); size += QSize(2*margin(), 2*margin()); return size;
}
int FlowLayout::doLayout(const QRect &rect, bool testOnly) const {
int left, top, right, bottom; getContentsMargins(&left, &top, &right, &bottom); QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom); int x = effectiveRect.x(); int y = effectiveRect.y(); int lineHeight = 0;
QLayoutItem *item; foreach (item, itemList) { QWidget *wid = item->widget(); int spaceX = horizontalSpacing(); if (spaceX == -1) spaceX = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal); int spaceY = verticalSpacing(); if (spaceY == -1) spaceY = wid->style()->layoutSpacing( QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
int nextX = x + item->sizeHint().width() + spaceX; if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) { x = effectiveRect.x(); y = y + lineHeight + spaceY; nextX = x + item->sizeHint().width() + spaceX; lineHeight = 0; } if (!testOnly) item->setGeometry(QRect(QPoint(x, y), item->sizeHint())); x = nextX; lineHeight = qMax(lineHeight, item->sizeHint().height()); } return y + lineHeight - rect.y() + bottom;
}
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const {
QObject *parent = this->parent(); if (!parent) { return -1; } else if (parent->isWidgetType()) { QWidget *pw = static_cast<QWidget *>(parent); return pw->style()->pixelMetric(pm, 0, pw); } else { return static_cast<QLayout *>(parent)->spacing(); }
}
- ifndef WINDOW_H
- define WINDOW_H
- include <QWidget>
QT_BEGIN_NAMESPACE class QLabel; QT_END_NAMESPACE class Window : public QWidget {
Q_OBJECT
public:
Window();
};
- endif
- include <QtGui>
- include "flowlayout.h"
- include "window.h"
Window::Window() {
FlowLayout *flowLayout = new FlowLayout; flowLayout->addWidget(new QPushButton(tr("Short"))); flowLayout->addWidget(new QPushButton(tr("Longer"))); flowLayout->addWidget(new QPushButton(tr("Different text"))); flowLayout->addWidget(new QPushButton(tr("More text"))); flowLayout->addWidget(new QPushButton(tr("Even longer button text"))); setLayout(flowLayout); setWindowTitle(tr("Flow Layout"));
}
- include <QApplication>
- include "window.h"
int main(int argc, char *argv[]) {
QApplication app(argc, argv); Window window; window.show(); return app.exec();
}
</source>