#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); // 放大elsescale(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中得效果。