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

相关推荐
ElvInR1 小时前
冒泡排序详解
c语言·c++·排序算法·冒泡排序
天若有情6731 小时前
探秘 C++ 计数器类:从基础实现到高级应用
java·开发语言·c++
hy____1232 小时前
list类的详细讲解
c++
范纹杉想快点毕业2 小时前
Google C++ Style Guide 谷歌 C++编码风格指南,深入理解华为与谷歌的编程规范——C和C++实践指南
c语言·数据结构·c++·qt·算法
幸运黒锦鲤2 小时前
Qt5、C++11 获取wifi列表与wifi连接
开发语言·qt
信奥洪老师3 小时前
2025年 全国青少年信息素养大赛 算法创意挑战赛C++ 小学组 初赛真题
c++·算法·青少年编程·等级考试
学习使我变快乐3 小时前
C++:关联容器set容器,multiset容器
开发语言·c++·算法
朱小勇本勇5 小时前
QT+R&SVisa控制LXI仪器
开发语言·qt
玉带湖水位记录员5 小时前
Qt+线段拖曳示例代码
开发语言·c++·qt