捕捉到网格不起作用

时间:2014-11-27 10:57:09

标签: qt qgraphicsview

我正在尝试捕捉网格,这样无论我将绘制它应该只采用网格点而没有其他点。我在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类看起来如下:

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

但没有任何事情发生,也没有完成抢断。你可以帮助我吗?

1 个答案:

答案 0 :(得分:1)

其中一个问题是您将QRect()传递给QGraphicsRectItem类初始化列表中的Snap构造函数。这意味着它将具有0宽度和高度。而是传递您传递给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);

然后将它们传递给基类构造函数:

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