qt – 在拖放时将QGraphicsItems与网格对齐

例如,如果我想使用QGraphicsView在游戏中显示玩家的库存,我怎么能强制执行基于网格的视图,其中拖放项目总是导致它们与网格对齐?

解决方法

您可以在QGraphicsScene子类中处理适当的鼠标事件:
#include <QApplication>
#include <QGraphicsItem>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsView>
#include <QMainWindow>

#include <math.h>

class GridScene : public QGraphicsScene
{
public:
    GridScene() :
        mCellSize(25,25)
    {
    }
protected:
    // Efficiently draws a grid in the background.
    // For more information: http://www.qtcentre.org/threads/5609-Drawing-grids-efficiently-in-QGraphicsScene?p=28905#post28905
    void drawBackground(QPainter *painter,const QRectF &rect)
    {
        qreal left = int(rect.left()) - (int(rect.left()) % mCellSize.width());
        qreal top = int(rect.top()) - (int(rect.top()) % mCellSize.height());

        QVarLengthArray<QLineF,100> lines;

        for (qreal x = left; x < rect.right(); x += mCellSize.width())
            lines.append(QLineF(x,rect.top(),x,rect.bottom()));
        for (qreal y = top; y < rect.bottom(); y += mCellSize.height())
            lines.append(QLineF(rect.left(),y,rect.right(),y));

        painter->drawLines(lines.data(),lines.size());
    }

    void mousepressEvent(QGraphicsSceneMouseEvent *mouseEvent)
    {
        mDragged = qgraphicsitem_cast<QGraphicsItem*>(itemAt(mouseEvent->scenePos(),QTransform()));
        if (mDragged) {
            mDragOffset = mouseEvent->scenePos() - mDragged->pos();
        } else
            QGraphicsScene::mousepressEvent(mouseEvent);
    }

    void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
    {
        if (mDragged) {
            // Ensure that the item's offset from the mouse cursor stays the same.
            mDragged->setPos(mouseEvent->scenePos() - mDragOffset);
        } else
            QGraphicsScene::mouseMoveEvent(mouseEvent);
    }

    void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
    {
        if (mDragged) {
            int x = floor(mouseEvent->scenePos().x() / mCellSize.width()) * mCellSize.width();
            int y = floor(mouseEvent->scenePos().y() / mCellSize.height()) * mCellSize.height();
            mDragged->setPos(x,y);
            mDragged = 0;
        } else
            QGraphicsScene::mouseReleaseEvent(mouseEvent);
    }
private:
    // The size of the cells in the grid.
    const QSize mCellSize;
    // The item being dragged.
    QGraphicsItem *mDragged;
    // The distance from the top left of the item to the mouse position.
    QPointF mDragOffset;
};

int main(int argc,char *argv[])
{
    QApplication a(argc,argv);
    QMainWindow w;
    w.resize(400,400);
    w.show();

    QGraphicsView view(&w);
    view.setScene(new GridScene());
    view.resize(w.size());
    view.setSceneRect(0,view.size().width(),view.size().height());
    view.show();

    view.scene()->addRect(0,25,25)->setBrush(QBrush(Qt::blue));

    return a.exec();
}

#include "main.moc"

相关文章

Css3如何实现鼠标移上变长特效?(图文+视频)
css3怎么实现鼠标悬停图片时缓慢变大效果?(图文+视频)
jquery如何实现点击网页回到顶部效果?(图文+视频)
css3边框阴影效果怎么做?(图文+视频)
css怎么实现圆角边框和圆形效果?(图文+视频教程)
Css3如何实现旋转移动动画特效