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

相关推荐
念恒123063 分钟前
继承(下) (Inheritance)
c++
H Journey1 小时前
C++之 CMake、CMakeLists.txt、Makefile
开发语言·c++·makefile·cmake
研究点啥好呢5 小时前
Github热门项目推荐 | 创建你的像素风格!
c++·python·node.js·github·开源软件
_dindong5 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
沫璃染墨6 小时前
C++ string 从入门到精通:构造、迭代器、容量接口全解析
c语言·开发语言·c++
6Hzlia6 小时前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode
计算机安禾7 小时前
【数据结构与算法】第36篇:排序大总结:稳定性、时间复杂度与适用场景
c语言·数据结构·c++·算法·链表·线性回归·visual studio
unicrom_深圳市由你创科技7 小时前
做虚拟示波器这种实时波形显示的上位机,用什么语言?
c++·python·c#
无限进步_7 小时前
【C++】电话号码的字母组合:从有限处理到通用解法
开发语言·c++·ide·windows·git·github·visual studio
C++ 老炮儿的技术栈7 小时前
GCC编译时无法向/tmp 目录写入临时汇编文件,因为设备空间不足,解决
linux·运维·开发语言·汇编·c++·git·qt