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

相关推荐
点云SLAM4 分钟前
C++ Template(模板)解读和模板报错如何“逆向阅读”定位
c++·c++20·c++模版·c++高级应用·c++模版报错定位
明洞日记14 分钟前
【数据结构手册008】STL容器完全参考指南
开发语言·数据结构·c++
农夫山泉2号1 小时前
【c++】——c++编译的so中函数有额外的字符
java·服务器·c++
水煎包V:YEDIYYDS8881 小时前
QT QML 实现的摇杆按钮,类似王者荣耀 左边方向导航键
qt·qml·摇杆按钮·导航键
仰泳的熊猫2 小时前
1077 Kuchiguse
数据结构·c++·算法·pat考试
WolfGang0073213 小时前
代码随想录算法训练营Day48 | 108.冗余连接、109.冗余连接II
数据结构·c++·算法
winfield8213 小时前
MCP 协议详解
开发语言·网络·qt
崇山峻岭之间3 小时前
C++ Prime Plus 学习笔记041
c++·笔记·学习
_风华ts4 小时前
虚函数与访问权限
c++
1001101_QIA4 小时前
C++中不能复制只能移动的类型
开发语言·c++