2013-02-24 25 views

risposta

7

È possibile gestire gli eventi appropriati del mouse in un QGraphicsScene sottoclasse:

#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, 0, view.size().width(), view.size().height()); 
    view.show(); 

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

    return a.exec(); 
} 

#include "main.moc"