2014-12-01 7 views
-1

그리드에 선을 그리고 스냅 기능을 구현하고 싶습니다. 격자와 선을 그렸지만 스냅 기능이 구현되지 않았습니다. 어떻게 그 기능을 구현할 수 있습니다.스냅이있는 그리기 선 그리기 기능

#include "line.h" 

Line::Line(int i, QPointF p1, QPointF p2) 
{ 
    // assigns id 
    id = i; 

    // set values of start point and end point of line 
    startP = p1; 
    endP = p2; 
} 

int Line::type() const 
{ 
    // Enable the use of qgraphicsitem_cast with line item. 
    return Type; 
} 

QRectF Line::boundingRect() const 
{ 
    qreal extra = 1.0; 

    // bounding rectangle for line 
    return QRectF(line().p1(), QSizeF(line().p2().x() - line().p1().x(), 
             line().p2().y() - line().p1().y())) 
      .normalized() 
      .adjusted(-extra, -extra, extra, extra); 
} 

void Line::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, 
        QWidget *widget) 
{ 
    // draws/paints the path of line 
    QPen paintpen; 
    painter->setRenderHint(QPainter::Antialiasing); 
    paintpen.setWidth(1); 

    if (isSelected()) 
    { 
     // sets brush for end points 
     painter->setBrush(Qt::SolidPattern); 
     paintpen.setColor(Qt::red); 
     painter->setPen(paintpen); 
     painter->drawEllipse(startP, 2, 2); 
     painter->drawEllipse(endP, 2, 2); 

     // sets pen for line path 
     paintpen.setStyle(Qt::DashLine); 
     paintpen.setColor(Qt::black); 
     painter->setPen(paintpen); 
     painter->drawLine(startP, endP); 
    } 

    else 
    { 
     painter->setBrush(Qt::SolidPattern); 
     paintpen.setColor(Qt::black); 
     painter->setPen(paintpen); 
     painter->drawEllipse(startP, 2, 2); 
     painter->drawEllipse(endP, 2, 2); 
     painter->drawLine(startP, endP); 
    } 
} 

이 snap.cpp이

#include "snap.h" 
#include <QApplication> 

    Snap::Snap(const QRect& rect, QGraphicsItem* parent, 
       QGraphicsScene* scene): 
    QGraphicsRectItem(QRectF()) 
    { 
     setFlags(QGraphicsItem::ItemIsSelectable | 
       QGraphicsItem::ItemIsMovable | 
       QGraphicsItem::ItemSendsGeometryChanges); 
    } 

    void Snap::mousePressEvent(QGraphicsSceneMouseEvent *event){ 
     offset = pos() - computeTopLeftGridPoint(pos()); 
     QGraphicsRectItem::mousePressEvent(event); 
    } 

    QVariant Snap::itemChange(GraphicsItemChange change, 
    const QVariant &value) 
    { 
     if (change == ItemPositionChange && scene()) { 
      QPointF newPos = value.toPointF(); 
      if(QApplication::mouseButtons() == Qt::LeftButton && 
       qobject_cast<CadGraphicsScene*> (scene())){ 
        QPointF closestPoint = computeTopLeftGridPoint(newPos); 
        return closestPoint+=offset; 
       } 
      else 
       return newPos; 
     } 
     else 
      return QGraphicsItem::itemChange(change, value); 
    } 

    QPointF Snap::computeTopLeftGridPoint(const QPointF& pointP){ 
     CadGraphicsScene* customScene = qobject_cast<CadGraphicsScene*> (scene()); 
     int gridSize = customScene->getGridSize(); 
     qreal xV = floor(pointP.x()/gridSize)*gridSize; 
     qreal yV = floor(pointP.y()/gridSize)*gridSize; 
     return QPointF(xV, yV); 
    } 

누군가가 나에게이 문제를 해결하는 데 도움시겠습니까 다음과 같이

void CadGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect) 
{ 
    if (isGridVisible) 
    { 
     const int gridSize = 50; 
     const int realLeft = static_cast<int>(std::floor(rect.left())); 
     const int realRight = static_cast<int>(std::ceil(rect.right())); 
     const int realTop = static_cast<int>(std::floor(rect.top())); 
     const int realBottom = static_cast<int>(std::ceil(rect.bottom())); 

     // Draw grid. 
     const int firstLeftGridLine = realLeft - (realLeft % gridSize); 
     const int firstTopGridLine = realTop - (realTop % gridSize); 
     QVarLengthArray<QLine, 100> lines; 

     for (qreal x = firstLeftGridLine; x <= realRight; x += gridSize) 
      lines.append(QLine(x, realTop, x, realBottom)); 
     for (qreal y = firstTopGridLine; y <= realBottom; y += gridSize) 
      lines.append(QLine(realLeft, y, realRight, y)); 

     painter->setPen(QPen(QColor(220, 220, 220), 0.0)); 
     painter->drawLines(lines.data(), lines.size()); 

     // Draw axes. 
     painter->setPen(QPen(Qt::lightGray, 0.0)); 
     painter->drawLine(0, realTop, 0, realBottom); 
     painter->drawLine(realLeft, 0, realRight, 0); 
    } 
} 

내 라인 클래스는 다음과 같이 나는 그리드를 그린? 당신이 스냅 할 항목의 MouseMoveEvent에서

답변

1

: 항목과 다음 눈금 선 사이의 거리가 일정 거리 (항목이 스냅인 것이다으로부터의 거리) 이하이면

확인합니다. 그런 다음 항목이 다음 GridLine으로 이동하도록 Position을 변경하십시오. 의사에서

는 :

if(distance(Item.Position, Grid.NextLine) < SnapDistance) 
    line.Position = Grid.MextLine.Position 

당신은 제대로이 일을 할 수 있지만 X와 Y를 분리해서해야합니다.

+0

예를 들어 주시겠습니까? – user3859872

+0

내가 한 일을 보여 주면 기꺼이 도와 주지만, 내가 쓸 시간이 없으므로 나는 해결책을 쓸 준비가되지 않을 것이다. – Mailerdaimon

+0

나는 그것을위한 스냅 클래스를 만들었습니다. 나는 그 안에 itemChange 함수를 사용했다. 그러나 이것을 사용하는 것은 짤깍 소리가 나지 않았습니다. 이유를 모르겠다. 내 코드를 업데이트했습니다. 이 문제를 해결하도록 도와주세요. – user3859872