QGrphicsScen画布网格和QGrphicsItem对齐到网格

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中得效果。

相关推荐
小龙报7 分钟前
《算法通关指南---C++编程篇(2)》
c语言·开发语言·数据结构·c++·程序人生·算法·学习方法
王夏奇1 小时前
C++友元函数和友元类!
开发语言·c++
xzal122 小时前
C++之理解共用体
c++
_OP_CHEN2 小时前
C++基础:(十六)priority_queue和deque的深度解析
开发语言·c++
C++ 老炮儿的技术栈2 小时前
include″″与includ<>的区别
c语言·开发语言·c++·算法·visual studio
BS_Li2 小时前
C++IO库
c++·io流
CHANG_THE_WORLD2 小时前
PDFium导出pdf 图像
开发语言·c++·pdf
Larry_Yanan2 小时前
QML学习笔记(四十三)QML与C++交互:上下文属性暴露
c++·笔记·qt·学习·ui·交互
owCode3 小时前
4-C++智能指针
开发语言·c++
liu****3 小时前
10.queue的模拟实现
开发语言·数据结构·c++·算法