2008年9月5日 星期五

qt - 透過滑鼠移動在canvas上的物件

參考資料:參考文檔的canvas example


void FigureEditor::contentsMousePressEvent(QMouseEvent* e)
{
  QPoint p = inverseWorldMatrix().map(e->pos()); // 可以改成p = inverseWorldMatrix()*(e->pos());
  QCanvasItemList l=canvas()->collisions(p);
  for (QCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) { // Iterator請參考這裡
    moving = *it;
    moving_start = p;
    return;
  }
  moving = 0;
}

QCanvasItem* moving; // 用來記錄要移動的qcanvasitem的指標
QPoint moving_start; // 用來記錄要移動的qcanvasitem的起始座標位址

這裡說明一下,it是指標性值的變數,是指到QCanvasItemList內的item的位置,所以,(*it)指的就是放在QCanvasItemList的東西,而我們這裡放的東西就是ImageItem,而ImageItem是由CanvasItem繼承過來的~ImageItem *item= (ImageItem*)(*it);,就是把基底類別(CanvasItem)的指標轉換成衍生類別(ImageItem)的指標

用到的function解釋

const QWMatrix & QCanvasView::inverseWorldMatrix () const
Returns a reference to the inverse of the canvasview's current transformation matrix.
回傳目前canvasview的反座標轉換物件的參照(reference)

QPoint QWMatrix::map ( const QPoint & p ) const
This function is obsolete. It is provided to keep old source working. We strongly advise against using it in new code.
這一個函式作廢了,請用下面運算代替
Does the same as operator *( const QPoint &)

const QPoint & QMouseEvent::pos () const
Returns the position of the mouse pointer relative to the widget that received the event.
傳回滑鼠的相對於目前widget的指標位置

QCanvasItemList QCanvas::collisions ( const QPoint & p ) const
Returns a list of canvas items that intersect with the point p. The list is ordered by z coordinates, from highest z coordinate (front-most item) to lowest z coordinate (rear-most item).
傳回所有與p點有交集的所有canvas item,且這一個list內的canvas item是由z大排到z小

QCanvas * QCanvasView::canvas () const
Returns a pointer to the canvas which the QCanvasView is currently showing.
目前qcanvasview所顯示的是某canvas,把此canvas的指標傳回



用到的類別解釋
The QCanvasItemList class is a list of QCanvasItems
QCanvasItemList is a QValueList of pointers to QCanvasItems. This class is used by some methods in QCanvas that need to return a list of canvas items.
QCanvasItemList是一連串QCanvasItem的pointer的集合,這一個class是被某一些canvas的function用來回傳一連串的QCanvasItem的pointer

延伸閱讀:
QValueList類是一個提供雙向鏈表(double-link)的基於值的模板類,也就是說是一個雙向鏈表,但是,裡面放什麼東西,還沒有定義,而QCanvasItemList就是繼承QValueList<QCanvasItem * >,也就是說雙向鏈表裡面放的是QCanvasItem的指標啦~


void FigureEditor::contentsMouseMoveEvent(QMouseEvent* e)
{
  if ( moving ) {
    QPoint p = inverseWorldMatrix().map(e->pos());
    moving->moveBy(p.x() - moving_start.x(),p.y() - moving_start.y());
    moving_start = p;
    canvas()->update();
  }
}



void QCanvasItem::moveBy ( double dx, double dy ) [virtual]
Moves the canvas item relative to its current position by (dx, dy).
移動canvas item對於目前的位置的相對偏移(dx,dy)
動作解析:滑鼠先移動到目的地,算出滑鼠與目前的座標差,而這個座標差就是相對於原位置的偏移~再根據這一個偏移值移動這一個canvas item

====================================================
總算完成透過滑鼠移動canvas item的程式了,
這裡要另外一說的就是,inverseWorldMatrix()只有當在設定完WorldMatrix之後,才會有效果,基本上,若沒有設定過,就不需要使用這一個function

沒有留言: