cpp
#include <QGraphicsScene>
#include <QPainter>
#include <QWheelEvent>
#include <QGraphicsView>
class MyGraphicsView : public QGraphicsView
{
public:
MyGraphicsView(QGraphicsScene* scene) : QGraphicsView(scene)
{
}
protected:
// 重写滚轮事件,实现缩放
void wheelEvent(QWheelEvent* event) override
{
// 使用滚轮进行缩放
if (event->angleDelta().y() > 0)
scale(1.2, 1.2); // 放大
else
scale(0.8, 0.8); // 缩小
}
};
class GridScene : public QGraphicsScene {
public:
GridScene(QObject* parent = nullptr) : QGraphicsScene(parent), gridSize(20) {}
void setGridSize(int size) {
gridSize = size;
update();
}
int gridSize1() const { return gridSize; }
protected:
void drawBackground(QPainter* painter, const QRectF& rect) override {
QGraphicsScene::drawBackground(painter, rect);
// 绘制网格
qreal left = int(rect.left()) - (int(rect.left()) % gridSize);
qreal top = int(rect.top()) - (int(rect.top()) % gridSize);
QVector<QLineF> lines;
for (qreal x = left; x < rect.right(); x += gridSize) {
lines.append(QLineF(x, rect.top(), x, rect.bottom()));
}
for (qreal y = top; y < rect.bottom(); y += gridSize) {
lines.append(QLineF(rect.left(), y, rect.right(), y));
}
painter->setPen(QPen(QColor(200, 200, 200), 1));
painter->drawLines(lines.data(), lines.size());
}
private:
int gridSize;
};
#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
class SnapItem : public QGraphicsItem {
public:
SnapItem(QGraphicsItem* parent = nullptr) : QGraphicsItem(parent) {
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsGeometryChanges);
}
QRectF boundingRect() const override {
return QRectF(122, 432, 64, 102); // 示例大小
}
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override {
painter->setBrush(Qt::blue);
painter->drawRect(boundingRect());
}
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant& value) override {
if (change == ItemPositionChange && scene()) {
// 获取场景中的网格大小
GridScene* gridScene = dynamic_cast<GridScene*>(scene());
if (gridScene) {
int gridSize = gridScene->gridSize1();
QPointF newPos = value.toPointF();
QRectF bounds = boundingRect();
QPointF offset = bounds.topLeft();
QPointF renderPos = newPos + offset;
qreal xV = round(renderPos.x() / gridSize) * gridSize - offset.x();
qreal yV = round(renderPos.y() / gridSize) * gridSize - offset.y();
return QPointF(xV, yV);
}
}
return QGraphicsItem::itemChange(change, value);
}
};
#include <QApplication>
#include <QGraphicsView>
int main(int argc, char* argv[]) {
QApplication a(argc, argv);
// 创建场景和视图
GridScene scene;
scene.setSceneRect(0, 0, 800, 600);
scene.setGridSize(57); // 设置网格大小
MyGraphicsView view(&scene);
view.setRenderHint(QPainter::Antialiasing);
view.setDragMode(QGraphicsView::RubberBandDrag);
view.show();
// 添加一些可吸附的item
/*for (int i = 0; i < 5; ++i) {
SnapItem* item = new SnapItem();
item->setPos(i * 100, i * 100);
scene.addItem(item);
}*/
SnapItem* item = new SnapItem();
item->setPos(122, 57);
scene.addItem(item);
SnapItem* item1 = new SnapItem();
item1->setPos(133, 87);
scene.addItem(item1);
SnapItem* item2 = new SnapItem();
item2->setPos(234, 97);
scene.addItem(item2);
return a.exec();
}
重写QGrphicsItem得itemChange方法即可实现对齐吸附到网格线,类似于ppt中得效果。