?? tutorial2-06.html
字號(hào):
m_elements[i].setProX( HORIZONTAL_BAR, proX );
m_elements[i].setProY( HORIZONTAL_BAR, proY );
</pre>
<p> 然后我們創(chuàng)建一個(gè)CanvasText條目,傳遞給它在元素矢量中這個(gè)元素的索引和所要使用的標(biāo)簽、字體和畫布。我們?cè)O(shè)置文本條目的顏色為用戶指定的顏色并且設(shè)置條目的x和y位置和畫布的寬高成比例。我們?cè)O(shè)置Z軸順序?yàn)?,這樣文本條目總是在條形(Z軸順序?yàn)?)的上面(前面)。我們調(diào)用show()函數(shù)在畫布上繪制文本條目,并且設(shè)置元素的相對(duì)x和y位置。
<p> <pre> }
y += proheight;
</pre>
<p> 在繪制完條形和可能存在的標(biāo)簽之后,我們給y增加一定比例的高度用來準(zhǔn)備繪制下一個(gè)元素。
<p> <pre> }
}
}
</pre>
<p> <h2> <a href="qcanvastext.html">QCanvasText</a>的子類
</h2>
<a name="2"></a><p> (由<tt>canvastext.h</tt>展開。)
<p>
<pre> class CanvasText : public <a href="qcanvastext.html">QCanvasText</a>
{
public:
enum { CANVAS_TEXT = 1100 };
CanvasText( int index, QCanvas *canvas )
: <a href="qcanvastext.html">QCanvasText</a>( canvas ), m_index( index ) {}
CanvasText( int index, const <a href="qstring.html">QString</a>& text, QCanvas *canvas )
: <a href="qcanvastext.html">QCanvasText</a>( text, canvas ), m_index( index ) {}
CanvasText( int index, const <a href="qstring.html">QString</a>& text, QFont font, QCanvas *canvas )
: <a href="qcanvastext.html">QCanvasText</a>( text, font, canvas ), m_index( index ) {}
int index() const { return m_index; }
void setIndex( int index ) { m_index = index; }
int rtti() const { return CANVAS_TEXT; }
private:
int m_index;
};
</pre>
<p> 我們的CanvasText子類是<a href="qcanvastext.html">QCanvasText</a>的一個(gè)非常簡單的特化。我們所做的一切只是添加一個(gè)私有成員<tt>m_index</tt>,它用來保存和這個(gè)文本相關(guān)的元素的元素矢量索引,并且提供為這個(gè)值提供一個(gè)讀和寫函數(shù)。
<p> <h2> <a href="qcanvasview.html">QCanvasView</a>的子類
</h2>
<a name="3"></a><p> (由<tt>canvasview.h</tt>展開。)
<p>
<pre> class CanvasView : public <a href="qcanvasview.html">QCanvasView</a>
{
<a href="metaobjects.html#Q_OBJECT">Q_OBJECT</a>
public:
CanvasView( <a href="qcanvas.html">QCanvas</a> *canvas, ElementVector *elements,
<a href="qwidget.html">QWidget</a>* parent = 0, const char* name = "canvas view",
WFlags f = 0 )
: <a href="qcanvasview.html">QCanvasView</a>( canvas, parent, name, f ),
m_elements( elements ) {}
protected:
void viewportResizeEvent( <a href="qresizeevent.html">QResizeEvent</a> *e );
void contentsMousePressEvent( <a href="qmouseevent.html">QMouseEvent</a> *e );
void contentsMouseMoveEvent( <a href="qmouseevent.html">QMouseEvent</a> *e );
void contentsContextMenuEvent( <a href="qcontextmenuevent.html">QContextMenuEvent</a> *e );
private:
<a href="qcanvasitem.html">QCanvasItem</a> *m_movingItem;
<a href="qpoint.html">QPoint</a> m_pos;
ElementVector *m_elements;
};
</pre>
<p> 我們需要繼承<a href="qcanvasview.html">QCanvasView</a>,這樣我們就能處理:
<ol type=1>
<li> 上下文菜單請(qǐng)求。
<li> 視窗重定義大小。
<li> 用戶拖拽標(biāo)簽到任意位置。
</ol>
<p> 為了支持這些,我們存儲(chǔ)一個(gè)到正在被移動(dòng)的畫布條目的指針和它的最終位置。我們也存儲(chǔ)一個(gè)到元素矢量的指針。
<p> <h3> 上下文菜單請(qǐng)求
</h3>
<a name="3-1"></a><p> (由<tt>canvasview.cpp</tt>展開。)
<p>
<pre> <a name="x2434"></a>void CanvasView::<a href="qscrollview.html#contentsContextMenuEvent">contentsContextMenuEvent</a>( <a href="qcontextmenuevent.html">QContextMenuEvent</a> * )
{
<a name="x2429"></a> ((ChartForm*)<a href="qobject.html#parent">parent</a>())->optionsMenu->exec( QCursor::<a href="qcursor.html#pos">pos</a>() );
}
</pre>
<p> 當(dāng)用戶調(diào)用一個(gè)上下文菜單(比如在絕大多數(shù)平臺(tái)通過右鍵點(diǎn)擊),我們把畫布視圖的父對(duì)象(是一個(gè)ChartForm)轉(zhuǎn)化為正確的類型,然后用exec()在光標(biāo)位置執(zhí)行選項(xiàng)菜單。
<p> <h3> 視窗重定義大小
</h3>
<a name="3-2"></a><p> <pre> <a name="x2437"></a>void CanvasView::<a href="qscrollview.html#viewportResizeEvent">viewportResizeEvent</a>( <a href="qresizeevent.html">QResizeEvent</a> *e )
{
<a name="x2433"></a> <a href="qcanvasview.html#canvas">canvas</a>()->resize( e-><a href="qresizeevent.html#size">size</a>().width(), e-><a href="qresizeevent.html#size">size</a>().height() );
((ChartForm*)<a href="qobject.html#parent">parent</a>())->drawElements();
}
</pre>
<p> 為了改變大小我們簡單地改變花布的大小,畫布視圖就會(huì)呈現(xiàn)在視窗客戶端區(qū)域的寬高中,然后調(diào)用drawElements()函數(shù)來重新繪制圖表。因?yàn)閐rawElements()畫的每一件都和畫布的寬高有關(guān),所以圖表就會(huì)被正確地繪制。
<p> <h3> 拖拽標(biāo)簽到任意位置
</h3>
<a name="3-3"></a><p> 當(dāng)用戶想把標(biāo)簽拖拽到他們點(diǎn)擊的位置時(shí),就應(yīng)該拖拽它并在新的位置釋放它。
<p> <pre> <a name="x2436"></a>void CanvasView::<a href="qscrollview.html#contentsMousePressEvent">contentsMousePressEvent</a>( <a href="qmouseevent.html">QMouseEvent</a> *e )
{
<a name="x2430"></a> <a href="qcanvasitemlist.html">QCanvasItemList</a> list = <a href="qcanvasview.html#canvas">canvas</a>()->collisions( e-><a href="qmouseevent.html#pos">pos</a>() );
<a name="x2439"></a><a name="x2438"></a> for ( QCanvasItemList::iterator it = list.<a href="qvaluelist.html#begin">begin</a>(); it != list.<a href="qvaluelist.html#end">end</a>(); ++it )
if ( (*it)->rtti() == CanvasText::CANVAS_TEXT ) {
m_movingItem = *it;
m_pos = e-><a href="qmouseevent.html#pos">pos</a>();
return;
}
m_movingItem = 0;
}
</pre>
<p> 當(dāng)用戶點(diǎn)擊鼠標(biāo)時(shí),我們創(chuàng)建一個(gè)鼠標(biāo)點(diǎn)擊“碰撞”(如果有的話)的畫布條目的列表。然后我們迭代這個(gè)列表并且如果我們發(fā)現(xiàn)一個(gè)<tt>CanvasText</tt>條目,我們就把它設(shè)置為移動(dòng)的條目并且記錄下它的位置。否則我們?cè)O(shè)置為不移動(dòng)條目。
<p> <pre> <a name="x2435"></a>void CanvasView::<a href="qscrollview.html#contentsMouseMoveEvent">contentsMouseMoveEvent</a>( <a href="qmouseevent.html">QMouseEvent</a> *e )
{
if ( m_movingItem ) {
<a href="qpoint.html">QPoint</a> offset = e-><a href="qmouseevent.html#pos">pos</a>() - m_pos;
<a name="x2432"></a><a name="x2431"></a> m_movingItem->moveBy( offset.<a href="qpoint.html#x">x</a>(), offset.<a href="qpoint.html#y">y</a>() );
m_pos = e-><a href="qmouseevent.html#pos">pos</a>();
ChartForm *form = (ChartForm*)<a href="qobject.html#parent">parent</a>();
form->setChanged( true );
int chartType = form->chartType();
CanvasText *item = (CanvasText*)m_movingItem;
int i = item->index();
(*m_elements)[i].setProX( chartType, item->x() / canvas()->width() );
(*m_elements)[i].setProY( chartType, item->y() / canvas()->height() );
<a href="qcanvasview.html#canvas">canvas</a>()->update();
}
}
</pre>
<p> 當(dāng)用戶拖拽鼠標(biāo)的時(shí)候,移動(dòng)事件就產(chǎn)生了。如果那里是一個(gè)可移動(dòng)條目,我們從鼠標(biāo)最后的位置和可移動(dòng)條目原來的位置計(jì)算出位移。我們將新的位置記錄為最后的位置。因?yàn)閳D表現(xiàn)在改變了,所以我們調(diào)用setChanged(),這樣當(dāng)用戶試圖退出或者讀入已存在的圖表時(shí)或者創(chuàng)建新的圖表,就會(huì)被提示是否保存。我們也分別地更新當(dāng)前圖表類型的元素的x和y的比例位置為當(dāng)前x和y與寬和高的比例。我們知道要更新哪個(gè)元件因?yàn)楫?dāng)我們創(chuàng)建每個(gè)畫布文本條目的時(shí)候,我們傳給它一個(gè)這個(gè)元素所對(duì)應(yīng)的位置索引。我們繼承了<a href="qcanvastext.html">QCanvasText</a>,這樣我們就可以設(shè)置和讀取這個(gè)索引值。最后我們調(diào)用update()來重繪畫布。
<p> <center><table cellpadding="4" cellspacing="2" border="0">
<tr bgcolor="#f0f0f0">
<td valign="top"><a href="qcanvas.html">QCanvas</a>沒有任何視覺效果。為了看到畫布的內(nèi)容,你必須創(chuàng)建一個(gè)<a href="qcanvasview.html">QCanvasView</a>來呈現(xiàn)畫布。如果條目被show()顯示,它們就會(huì)出現(xiàn)在畫布視圖中,然后,只有當(dāng)<a href="qcanvas.html#update">QCanvas::update</a>()被調(diào)用的時(shí)候。默認(rèn)情況下QCanva的背景是白色,并且會(huì)在畫布上繪制默認(rèn)的形狀,比如<a href="qcanvasrectangle.html">QCanvasRectangle</a>、<a href="qcanvasellipse.html">QCanvasEllipse</a>等等,因?yàn)樗鼈儽话咨畛洌苑浅M扑]使用一個(gè)非白色的畫刷顏色!
</table></center>
<p> <p align=right>
<a href="tutorial2-05.html">« 實(shí)現(xiàn)圖形用戶界面</a> |
<a href="tutorial2.html">目錄</a> |
<a href="tutorial2-07.html">文件處理 »</a>
</p>
<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>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -