2014-11-27 7 views
0

Я пытаюсь сделать привязку к сетке таким образом, чтобы все, что бы я ни рисовал, должно принимать только точки сетки и никакие другие точки. Я сделал сетку в cadgraphicsscene.cpp и сделал другой класс для привязки. Моя сетка производится следующим образом:Привязка к сетке не работает

cadgraphicscene.cpp

void CadGraphicsScene::drawBackground(QPainter *painter, const QRectF &rect) 
{ 
    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); 
} 

Мой класс оснастки выглядит следующим образом:

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); 
    } 

snap.h

#ifndef SNAP_H 
#define SNAP_H 

#include <QGraphicsRectItem> 
#include "cadgraphicsscene.h" 

class Snap : public QGraphicsRectItem 
{ 
public: 
    Snap(const QRect& rect, QGraphicsItem* parent, 
     QGraphicsScene* scene); 
protected: 
    void mousePressEvent(QGraphicsSceneMouseEvent *event); 
    QVariant itemChange(GraphicsItemChange change, 
    const QVariant &value); 
private: 
    QPointF offset; 
    QPointF computeTopLeftGridPoint(const QPointF &pointP); 
}; 

#endif // SNAP_H 

Но ничего не произошло, никаких щелчков не было сделано. Не могли бы вы помочь мне в этом?

+0

Попробуйте некоторые отладки. Посмотрите, как далеко он переходит в функцию 'itemChange'. – thuga

+0

Когда я запускаю отладчик, он нигде не останавливается. Я не могу решить, где проблема. Пожалуйста, помогите мне. – user3859872

+0

Добавить точки останова и начать шаг за шагом. – thuga

ответ

1

Одна из проблем заключается в том, что вы передаете QRect() в конструктор QGraphicsRectItem в списке инициализации класса Snap. Это означает, что он будет иметь ширину и высоту. Вместо того, чтобы пройти один и тот же QRect объект, который вы передаете в вашей оснастке конструктору:

Snap::Snap(const QRect& rect, QGraphicsItem* parent, QGraphicsScene* scene) : 
QGraphicsRectItem(rect) 

Вы также, кажется, не использовать родителя и аргументы сцены, так что вы могли бы также оставить их:

Snap::Snap(const QRect& rect) : 
    QGraphicsRectItem(rect) 

Или, если вы планируете использовать родительский для чего-то, то вы можете установить значение по умолчанию 0 в объявлении:

Snap(const QRect& rect, QGraphicsItem* parent = 0); 

затем передайте их как базовый класс сопзЬ ructor:

Snap::Snap(const QRect& rect, QGraphicsItem* parent) : 
QGraphicsRectItem(rect, parent) 

snap.h

#ifndef SNAP_H 
#define SNAP_H 

#include <QGraphicsRectItem> 

class Snap : public QGraphicsRectItem 
{ 
public: 
    Snap(const QRect &rect, QGraphicsItem *parent = 0); 
protected: 
    void mousePressEvent(QGraphicsSceneMouseEvent *event); 
    QVariant itemChange(GraphicsItemChange change, 
    const QVariant &value); 
private: 
    QPointF offset; 
    QPointF computeTopLeftGridPoint(const QPointF &pointP); 
}; 

#endif // SNAP_H 

snap.cpp

#include "snap.h" 
#include <QDebug> 
#include <qmath.h> 

Snap::Snap(const QRect& rect, QGraphicsItem* parent) : 
    QGraphicsRectItem(rect, parent) 
{ 
    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) 
{ 
    qDebug()<<"inside itemChange"; 
    if (change == ItemPositionChange && scene()) 
    { 
     QPointF newPos = value.toPointF(); 
     QPointF closestPoint = computeTopLeftGridPoint(newPos); 
     return closestPoint+=offset; 
    } 
    else 
     return QGraphicsItem::itemChange(change, value); 
} 

QPointF Snap::computeTopLeftGridPoint(const QPointF& pointP){ 
    int gridSize = 100; 
    qreal xV = qFloor(pointP.x()/gridSize)*gridSize; 
    qreal yV = qFloor(pointP.y()/gridSize)*gridSize; 
    return QPointF(xV, yV); 
} 

mainwindow.cpp

#include "mainwindow.h" 
#include "ui_mainwindow.h" 

#include <QGraphicsView> 
#include <QLayout> 
#include "snap.h" 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    centralWidget()->setLayout(new QVBoxLayout); 
    QGraphicsView *view = new QGraphicsView(this); 
    centralWidget()->layout()->addWidget(view); 
    Snap *snap = new Snap(QRect(0,0,100,100)); 
    view->setScene(new QGraphicsScene); 
    view->scene()->addItem(snap); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 
Смежные вопросы