我正在尝试捕捉网格,这样无论我将绘制它应该只采用网格点而没有其他点。我在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
但没有任何事情发生,也没有完成抢断。你可以帮助我吗?
答案 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;
}