summaryrefslogtreecommitdiffstats
path: root/doc/html/customlayout.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/html/customlayout.html')
-rw-r--r--doc/html/customlayout.html246
1 files changed, 246 insertions, 0 deletions
diff --git a/doc/html/customlayout.html b/doc/html/customlayout.html
new file mode 100644
index 0000000..1a46c6d
--- /dev/null
+++ b/doc/html/customlayout.html
@@ -0,0 +1,246 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!-- /home/espenr/tmp/qt-3.3.8-espenr-2499/qt-x11-free-3.3.8/doc/layout.doc:285 -->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Writing your own layout manager</title>
+<style type="text/css"><!--
+fn { margin-left: 1cm; text-indent: -1cm; }
+a:link { color: #004faf; text-decoration: none }
+a:visited { color: #672967; text-decoration: none }
+body { background: #ffffff; color: black; }
+--></style>
+</head>
+<body>
+
+<table border="0" cellpadding="0" cellspacing="0" width="100%">
+<tr bgcolor="#E5E5E5">
+<td valign=center>
+ <a href="index.html">
+<font color="#004faf">Home</font></a>
+ | <a href="classes.html">
+<font color="#004faf">All&nbsp;Classes</font></a>
+ | <a href="mainclasses.html">
+<font color="#004faf">Main&nbsp;Classes</font></a>
+ | <a href="annotated.html">
+<font color="#004faf">Annotated</font></a>
+ | <a href="groups.html">
+<font color="#004faf">Grouped&nbsp;Classes</font></a>
+ | <a href="functions.html">
+<font color="#004faf">Functions</font></a>
+</td>
+<td align="right" valign="center"><img src="logo32.png" align="right" width="64" height="32" border="0"></td></tr></table><h1 align=center>Writing your own layout manager</h1>
+
+
+<p> Here we present an example in detail. The class CardLayout is inspired
+by the Java layout manager of the same name. It lays out the items
+(widgets or nested layouts) on top of each other, each item offset by
+<a href="qlayout.html#spacing">QLayout::spacing</a>().
+<p> To write your own layout class, you must define the following:
+<ul>
+<li> A data structure to store the items handled by the layout. Each
+item is a <a href="qlayoutitem.html">QLayoutItem</a>. We will use a
+<a href="qptrlist.html">QPtrList</a> in this example.
+<li> <a href="qlayout.html#addItem">addItem()</a>, how to add items to
+the layout.
+<li> <a href="qlayout.html#setGeometry">setGeometry()</a>, how to perform
+the layout.
+<li> <a href="qlayoutitem.html#sizeHint">sizeHint()</a>, the preferred size
+of the layout.
+<li> <a href="qlayout.html#iterator">iterator()</a>, how to iterate over
+the layout.
+</ul>
+<p> In most cases, you will also implement <a href="qlayout.html#minimumSize">minimumSize</a>().
+<p> <h2> card.h
+</h2>
+<a name="1"></a><p> <pre>
+#ifndef CARD_H
+#define CARD_H
+
+#include &lt;<a href="qlayout-h.html">qlayout.h</a>&gt;
+#include &lt;<a href="qptrlist-h.html">qptrlist.h</a>&gt;
+
+class CardLayout : public <a href="qlayout.html">QLayout</a>
+{
+public:
+ CardLayout( <a href="qwidget.html">QWidget</a> *parent, int dist )
+ : <a href="qlayout.html">QLayout</a>( parent, 0, dist ) {}
+ CardLayout( <a href="qlayout.html">QLayout</a>* parent, int dist)
+ : <a href="qlayout.html">QLayout</a>( parent, dist ) { }
+ CardLayout( int dist )
+ : <a href="qlayout.html">QLayout</a>( dist ) {}
+ ~CardLayout();
+
+ void addItem(QLayoutItem *item);
+ <a href="qsize.html">QSize</a> sizeHint() const;
+ <a href="qsize.html">QSize</a> minimumSize() const;
+ <a href="qlayoutiterator.html">QLayoutIterator</a> iterator();
+ void setGeometry(const <a href="qrect.html">QRect</a> &amp;rect);
+
+private:
+ <a href="qptrlist.html">QPtrList</a>&lt;QLayoutItem&gt; list;
+};
+
+#endif
+</pre>
+
+<p> <h3> card.cpp
+</h3>
+<a name="1-1"></a><p> <pre>
+#include "card.h"
+</pre>
+
+<p> First we define an iterator over the layout. Layout iterators are used
+internally by the layout system to handle deletion of widgets. They
+are also available for application programmers.
+<p> There are two different classes involved: <a href="qlayoutiterator.html">QLayoutIterator</a> is the class
+that is visible to application programmers, it is <a href="shclass.html#explicitly-shared">explicitly shared</a>.
+The QLayoutIterator contains a <a href="qglayoutiterator.html">QGLayoutIterator</a> that does all the
+work. We must create a subclass of QGLayoutIterator that knows how to
+iterate over our layout class.
+<p> In this case, we choose a simple implementation: we store an integer
+index into the list and a pointer to the list. Every <a href="qglayoutiterator.html">QGLayoutIterator</a> subclass must implement <a href="qglayoutiterator.html#current">current</a>(), <a href="qglayoutiterator.html#next">next</a>() and <a href="qglayoutiterator.html#takeCurrent">takeCurrent</a>(), as well as a
+constructor. In our example we do not need a destructor.
+<p> <pre>
+class CardLayoutIterator : public <a href="qglayoutiterator.html">QGLayoutIterator</a>
+{
+public:
+ CardLayoutIterator( <a href="qptrlist.html">QPtrList</a>&lt;QLayoutItem&gt; *l )
+ : idx( 0 ), list( l ) {}
+
+ <a href="qlayoutitem.html">QLayoutItem</a> *current()
+ { return idx &lt; int(list-&gt;<a href="qptrlist.html#count">count</a>()) ? list-&gt;<a href="qptrlist.html#at">at</a>(idx) : 0; }
+
+ <a href="qlayoutitem.html">QLayoutItem</a> *next()
+ { idx++; return current(); }
+
+ <a href="qlayoutitem.html">QLayoutItem</a> *takeCurrent()
+ { return list-&gt;<a href="qptrlist.html#take">take</a>( idx ); }
+
+private:
+ int idx;
+ <a href="qptrlist.html">QPtrList</a>&lt;QLayoutItem&gt; *list;
+};
+</pre>
+
+<p> We must implement QLayout:iterator() to return a <a href="qlayoutiterator.html">QLayoutIterator</a> over
+this layout.
+<p> <pre>
+QLayoutIterator CardLayout::iterator()
+{
+ return QLayoutIterator( new CardLayoutIterator(&amp;list) );
+}
+</pre>
+
+<p> addItem() implements the default placement strategy for layout items.
+It must be implemented. It is used by <a href="qlayout.html#add">QLayout::add</a>(), by the <a href="qlayout.html">QLayout</a>
+constructor that takes a layout as parent, and it is used to implement
+the <a href="qlayout.html#autoAdd">auto-add</a> feature. If your layout
+has advanced placement options that require parameters, you must
+provide extra access functions such as <a href="qgridlayout.html#addMultiCell">QGridLayout::addMultiCell</a>().
+<p> <pre>
+void CardLayout::addItem( <a href="qlayoutitem.html">QLayoutItem</a> *item )
+{
+ list.append( item );
+}
+</pre>
+
+<p> The layout takes over responsibility of the items added. Since
+<a href="qlayoutitem.html">QLayoutItem</a> does not inherit <a href="qobject.html">QObject</a>, we must delete the items
+manually. The function <a href="qlayout.html#deleteAllItems">QLayout::deleteAllItems</a>() uses the iterator we
+defined above to delete all the items in the layout.
+<p> <pre>
+CardLayout::~CardLayout()
+{
+ deleteAllItems();
+}
+</pre>
+
+<p> The setGeometry() function actually performs the layout. The rectangle
+supplied as an argument does not include margin(). If relevant, use
+spacing() as the distance between items.
+<p> <pre>
+void CardLayout::setGeometry( const <a href="qrect.html">QRect</a> &amp;rect )
+{
+ QLayout::<a href="qlayout.html#setGeometry">setGeometry</a>( rect );
+
+ <a href="qptrlistiterator.html">QPtrListIterator</a>&lt;QLayoutItem&gt; it( list );
+ if (it.<a href="qptrlistiterator.html#count">count</a>() == 0)
+ return;
+
+ <a href="qlayoutitem.html">QLayoutItem</a> *item;
+
+ int i = 0;
+
+ int w = rect.<a href="qrect.html#width">width</a>() - ( list.count() - 1 ) * spacing();
+ int h = rect.<a href="qrect.html#height">height</a>() - ( list.count() - 1 ) * spacing();
+
+ while ( (item = it.<a href="qptrlistiterator.html#current">current</a>()) != 0 ) {
+ ++it;
+ <a href="qrect.html">QRect</a> geom( rect.<a href="qrect.html#x">x</a>() + i * spacing(), rect.<a href="qrect.html#y">y</a>() + i * spacing(),
+ w, h );
+ item-&gt;<a href="qlayoutitem.html#setGeometry">setGeometry</a>( geom );
+ ++i;
+ }
+}
+</pre>
+
+<p> sizeHint() and minimumSize() are normally very similar in
+implementation. The sizes returned by both functions should include
+spacing(), but not margin().
+<p> <pre>
+QSize CardLayout::sizeHint() const
+{
+ <a href="qsize.html">QSize</a> s( 0, 0 );
+ int n = list.count();
+ if ( n &gt; 0 )
+ s = QSize( 100, 70 ); // start with a nice default size
+ <a href="qptrlistiterator.html">QPtrListIterator</a>&lt;QLayoutItem&gt; it( list );
+ <a href="qlayoutitem.html">QLayoutItem</a> *item;
+ while ( (item = it.<a href="qptrlistiterator.html#current">current</a>()) != 0 ) {
+ ++it;
+ s = s.<a href="qsize.html#expandedTo">expandedTo</a>( item-&gt;<a href="qlayoutitem.html#minimumSize">minimumSize</a>() );
+ }
+ return s + n * QSize( spacing(), spacing() );
+}
+
+QSize CardLayout::minimumSize() const
+{
+ <a href="qsize.html">QSize</a> s( 0, 0 );
+ int n = list.count();
+ <a href="qptrlistiterator.html">QPtrListIterator</a>&lt;QLayoutItem&gt; it( list );
+ <a href="qlayoutitem.html">QLayoutItem</a> *item;
+ while ( (item = it.<a href="qptrlistiterator.html#current">current</a>()) != 0 ) {
+ ++it;
+ s = s.<a href="qsize.html#expandedTo">expandedTo</a>( item-&gt;<a href="qlayoutitem.html#minimumSize">minimumSize</a>() );
+ }
+ return s + n * QSize( spacing(), spacing() );
+}
+</pre>
+
+<p> <h2> Further Notes
+</h2>
+<a name="2"></a><p> This layout does not implement heightForWidth().
+<p> We ignore <a href="qlayoutitem.html#isEmpty">QLayoutItem::isEmpty</a>(), this means that the layout will
+treat hidden widgets as visible.
+<p> For complex layouts, speed can be greatly increased by caching
+calculated values. In that case, implement <a href="qlayoutitem.html#invalidate">QLayoutItem::invalidate</a>()
+to mark the cached data as dirty.
+<p> Calling <a href="qlayoutitem.html#sizeHint">QLayoutItem::sizeHint</a>(), etc. may be expensive, so you should
+store the value in a local variable if you need it again later in the
+same function.
+<p> You should not call <a href="qlayoutitem.html#setGeometry">QLayoutItem::setGeometry</a>() twice on the same item
+in the same function. That can be very expensive if the item has
+several child widgets, because it will have to do a complete layout
+every time. Instead, calculate the geometry and then set it. (This
+doesn't only apply to layouts, you should do the same if you implement
+your own resizeEvent().)
+<p>
+<!-- eof -->
+<p><address><hr><div align=center>
+<table width=100% cellspacing=0 border=0><tr>
+<td>Copyright &copy; 2007
+<a href="troll.html">Trolltech</a><td align=center><a href="trademarks.html">Trademarks</a>
+<td align=right><div align=right>Qt 3.3.8</div>
+</table></div></address></body>
+</html>