?? customlayout.html
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- /home/reggie/tmp/qt-3.0-reggie-5401/qt-win-commercial-3.0.5/doc/layout.doc:270 -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="Translator" content="Cavendish">
<meta name="Qt zh_CN Documents Website" content="http://www.qiliang.net/qt">
<title>寫你自己的布局管理器</title>
<style type="text/css"><!--
h3.fn,span.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; font-family: "Times New Roman" }
--></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">主頁</font></a>
| <a href="classes.html">
<font color="#004faf">所有的類</font></a>
| <a href="mainclasses.html">
<font color="#004faf">主要的類</font></a>
| <a href="annotated.html">
<font color="#004faf">注釋的類</font></a>
| <a href="groups.html">
<font color="#004faf">分組的類</font></a>
| <a href="functions.html">
<font color="#004faf">函數(shù)</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>寫你自己的布局管理器</h1>
<p> 要寫自己的布局類,你必須像下面這樣定義:
<ul>
<li> 一個用來存放被布局處理的項目的數(shù)據(jù)結(jié)構(gòu)。每一個項目就是一個<a href="qlayoutitem.html">QLayoutItem</a>。我們將在例子中使用一個<a href="qptrlist.html">QPtrList</a>。
<li> <a href="qlayout.html#addItem">addItem()</a>,如何向布局中添加一個項目。
<li> <a href="qlayout.html#setGeometry">setGeometry()</a>,如何構(gòu)成一個布局。
<li> <a href="qlayoutitem.html#sizeHint">sizeHint()</a>,布局優(yōu)先選用的大小。
<li> <a href="qlayout.html#iterator">iterator()</a>,如何迭代布局。
</ul>
<p> 在絕大多數(shù)情況下,你也需要實現(xiàn)<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 <<a href="qlayout-h.html">qlayout.h</a>>
#include <<a href="qptrlist-h.html">qptrlist.h</a>>
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> &rect);
private:
<a href="qptrlist.html">QPtrList</a><QLayoutItem> list;
};
#endif
</pre>
<p> <h3> card.cpp
</h3>
<a name="1-1"></a><p> <pre>
#include "card.h"
</pre>
<p> 首先我們?yōu)椴季侄x一個迭代。布局迭代被布局系統(tǒng)用作內(nèi)部處理圖形窗口部件刪除操作的。它們也可以被提供給應用程序員。
<p> 這里有兩個兩個不同的相關類:<a href="qlayoutiterator.html">QLayoutIterator</a>是一個可以提供給應用程序員可見的類,它是<a href="shclass.html#explicitly-shared">明確地被共享</a>。QLayoutIterator包括一個可以做任何事情地<a href="qglayoutiterator.html">QGLayoutIterator</a>。我們必須生成一個知道如何迭代我們地布局類的QGLayoutIterator的子類。
<p> 在這種情況下,我們選擇一個簡單的實現(xiàn):我們把一個整數(shù)索引和指針存儲到一個列表中。每一個<a href="qglayoutiterator.html">QGLayoutIterator</a>的子類都必須實現(xiàn)<a href="qglayoutiterator.html#current">current</a>()、<a href="qglayoutiterator.html#next">next</a>()和<a href="qglayoutiterator.html#takeCurrent">takeCurrent</a>(),還有一個構(gòu)造函數(shù)。在我們的例子中我們不需要析構(gòu)函數(shù)。
<p> <pre>
class CardLayoutIterator : public <a href="qglayoutiterator.html">QGLayoutIterator</a>
{
public:
CardLayoutIterator( <a href="qptrlist.html">QPtrList</a><QLayoutItem> *l )
: idx( 0 ), list( l ) { }
<a href="qlayoutitem.html">QLayoutItem</a> *current()
{ return idx < int(list-><a href="qptrlist.html#count">count</a>()) ? list-><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-><a href="qptrlist.html#take">take</a>( idx ); }
private:
int idx;
<a href="qptrlist.html">QPtrList</a><QLayoutItem> *list;
};
</pre>
<p> 我們必須實現(xiàn)QLayout:iterator()返回一個這個布局的<a href="qlayoutiterator.html">QLayoutIterator</a>。
<p> <pre>
QLayoutIterator CardLayout::iterator()
{
return QLayoutIterator( new CardLayoutIterator(&list) );
}
</pre>
<p> addItem()實現(xiàn)了布局項目的默認布置策略。它必須被實現(xiàn)。它被<a href="qlayout.html#add">QLayout::add</a>()使用,被把一個布局作為父布局的<a href="qlayout.html">QLayout</a>的構(gòu)造函數(shù)使用,并且它被用來實現(xiàn)<a href="qlayout.html#autoAdd">自動添加</a>這一特性。如果你的布局有需要參數(shù)的高級布置選項,你將必須提供像<a href="qgridlayout.html#addMultiCell">QGridLayout::addMultiCell</a>()一樣的額外的訪問函數(shù)。
<p> <pre>
void CardLayout::addItem( <a href="qlayoutitem.html">QLayoutItem</a> *item )
{
list.append( item );
}
</pre>
<p> 布局對項目的增加負有責任。因為<a href="qlayoutitem.html">QLayoutItem</a>不繼承<a href="qobject.html">QObject</a>,我們必須人工地刪除這些項目。<a href="qlayout.html#deleteAllItems">QLayout::deleteAllItems</a>()函數(shù)使用我們前面定義的迭代來刪除布局中的所有項目。
<p> <pre>
CardLayout::~CardLayout()
{
deleteAllItems();
}
</pre>
<p> setGeometry()函數(shù)實際上執(zhí)行了這個布局。作為參數(shù)提供的矩形不包括margin()。如果相關的話,項目之間的距離請使用spacing()。
<p> <pre>
void CardLayout::setGeometry( const <a href="qrect.html">QRect</a> &rect )
{
QLayout::<a href="qlayout.html#setGeometry">setGeometry</a>( rect );
<a href="qptrlistiterator.html">QPtrListIterator</a><QLayoutItem> it( list );
if (it.<a href="qptrlistiterator.html#count">count</a>() == 0)
return;
<a href="qlayoutitem.html">QLayoutItem</a> *o;
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 ( (o = 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 );
o-><a href="qlayoutitem.html#setGeometry">setGeometry</a>( geom );
++i;
}
}
</pre>
<p> sizeHint()和minimumSize()通常情況下在實現(xiàn)中非常相似。這兩個函數(shù)返回的大小應該包括spacing(),但不包括margin()。
<p> <pre>
QSize CardLayout::sizeHint() const
{
<a href="qsize.html">QSize</a> s( 0, 0 );
int n = list.count();
if ( n > 0 )
s = QSize( 100, 70 ); // start with a nice default size
<a href="qptrlistiterator.html">QPtrListIterator</a><QLayoutItem> it( list );
<a href="qlayoutitem.html">QLayoutItem</a> *o;
while ( (o = it.<a href="qptrlistiterator.html#current">current</a>()) != 0 ) {
++it;
s = s.<a href="qsize.html#expandedTo">expandedTo</a>( o-><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><QLayoutItem> it( list );
<a href="qlayoutitem.html">QLayoutItem</a> *o;
while ( (o = it.<a href="qptrlistiterator.html#current">current</a>()) != 0 ) {
++it;
s = s.<a href="qsize.html#expandedTo">expandedTo</a>( o-><a href="qlayoutitem.html#minimumSize">minimumSize</a>() );
}
return s + n * QSize( spacing(), spacing() );
}
</pre>
<p> <h2> 更多的注釋
</h2>
<a name="2"></a><p> 這個布局沒有實現(xiàn)heightForWidth()。
<p> 我們忽略了<a href="qlayoutitem.html#isEmpty">QLayoutItem::isEmpty</a>(),這也就是說這個布局將會把隱藏的窗口部件顯示出來。
<p> 對于復雜的布局,通過存儲計算結(jié)果可以使速度得到很大的提高。在這種情況下,實現(xiàn)<a href="qlayoutitem.html#invalidate">QLayoutItem::invalidate</a>()來把被存儲的數(shù)據(jù)弄臟。
<p> 調(diào)用<a href="qlayoutitem.html#sizeHint">QLayoutItem::sizeHint</a>(),其它的也許更浪費時間,如果你在同一個函數(shù)中再一次稍晚的情況下需要這個值,你應該把它存儲成局部變量。
<p> 你不應該在同一個函數(shù)中對同一項目調(diào)用<a href="qlayoutitem.html#setGeometry">QLayoutItem::setGeometry</a>()兩次。如果這個項目有幾個子窗口部件的話,它會很浪費時間,因為它將不得不每次都執(zhí)行一個完整的布局。相反,計算幾何位置并且設置它。(這不僅僅是應用于布局,如果你實現(xiàn)了你自己的resizeEvent()你應該做同樣的事情。)
<p>
<!-- eof -->
<p><address><hr><div align=center>
<table width=100% cellspacing=0 border=0><tr>
<td>Copyright © 2002
<a href="http://www.trolltech.com">Trolltech</a>
<td><a href="http://www.trolltech.com/trademarks.html">Trademarks</a>
<td><a href="zh_CN.html">譯者:Cavendish</a>
<td align=right><div align=right>Qt 3.0.5版</div>
</table></div></address></body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -