2014-11-01 48 views
0

我對我的實體有不同的子類。這些實體是在GraphicsView中繪製的,如何將剪貼板操作應用於剪切,複製和粘貼。圖形視圖中的剪貼板操作

gEntity.h

#ifndef GENTITY_H 
#define GENTITY_H 
class gEntity :public QObject 
{ 

public: 
    gEntity(QObject* parent=0) : QObject(parent) {} 
    virtual ~gEntity() {} 

    virtual gEntity* my_clone() { return 0; } 
}; 

#endif // GENTITY_H 

circle.h

#ifndef CIRCLE_H 
    #define CIRCLE_H 

    #include <QPainter> 
    #include <QGraphicsItem> 
    #include <gentity.h> 

    #include "qmath.h" 


    class Circle : public QObject, public QGraphicsItem, public gEntity 
    { 
     Q_OBJECT 

    public: 
     Circle(QObject* parent=0) : gEntity(parent){ 

     } 

     Circle(int, QPointF, QPointF); 
     Circle(int, QPointF, qreal); 
     QRectF boundingRect() const; 
     virtual void paint(QPainter *painter, 
          const QStyleOptionGraphicsItem *option, 
          QWidget *widget); 
     enum { Type = UserType + 3 }; 
     int type() const; 
     int id; 

     QPointF center_p, end_p, move_p; 
     qreal radius; 
     void setRadius((const qreal &radius); 

     private: 
     QVector<QPointF> stuff; 
    }; 

#endif // CIRCLE_H 

circle.cpp

#include "circle.h" 
#include "gentity.h" 

Circle::Circle(int i, QPointF p1, QPointF p2) 
{ 
    // assigns id 
    id = i; 

    /* set values of center point, end point 
    and calculate radius of circle */ 
    center_p = p1; 
    end_p = p2; 
    radius = qSqrt(qPow((end_p.x()-center_p.x()), 2) 
        + qPow((end_p.y()-center_p.y()), 2)); 
} 

Circle::Circle(int i, QPointF p1, qreal rad) 
{ 
    // assigns id 
    id = i; 

    /* set values of center point 
     and radius of circle */ 
    center_p = p1; 
    radius = rad; 
} 

int Circle::type() const 
{ 
    // Enable the use of qgraphicsitem_cast with circle item. 
    return Type; 
} 

QRectF Circle::boundingRect() const 
{ 
    // bounding rectangle for circle 
    return QRectF((center_p.x()-radius), (center_p.y()-radius), 
        (2*radius), (2*radius)); 
} 

void Circle::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, 
        QWidget *widget) 
{ 
    // draws/paints the path of circle 
    QPen paintpen(Qt::black); 
    paintpen.setWidth(1); 
    painter->setRenderHint(QPainter::Antialiasing); 

    if (isSelected()) 
    { 
     // sets brush for center point 
     painter->setBrush(Qt::SolidPattern); 
     paintpen.setColor(Qt::red); 
     painter->setPen(paintpen); 
     painter->drawEllipse(center_p, 2, 2); 

     // sets pen for circumference 
     paintpen.setStyle(Qt::DashLine); 
     paintpen.setColor(Qt::black); 
     painter->setBrush(Qt::NoBrush); 
     painter->setPen(paintpen); 
     painter->drawEllipse(center_p, radius, radius); 
    } 
    else 
    { painter->save(); 
     painter->setBrush(Qt::SolidPattern); 
     paintpen.setColor(Qt::black); 
     painter->setPen(paintpen); 
     painter->drawEllipse(center_p, 2, 2); 
     painter->setBrush(Qt::NoBrush); 
     painter->drawEllipse(center_p, radius, radius); 
     painter->restore(); 
    } 
} 
gEntity* my_clone(){ 
    Circle *c = new Circle(); 
    c->setRadius(radius); 
    return c; 

} 

Clipboard.h

#include<QStack> 
#include<QClipboard> 
class MyClipBoard 
{ 
public: 
    static MyClipBoard* instance() 
    { 
     if(!inst) 
      inst = new MyClipBoard; 
     return inst; 
    } 

    void push(gEntity* g) { 
     clips.push(g); 
    } 

    gEntity* last() 
    { 
     if(clips.count() == 0) return 0; 
     return clips.last(); 
    } 

    gEntity* pop() 
    { 
     if(clips.count() == 0) return 0; 
     return clips.pop(); 
    } 

    bool isempty() const { return clips.empty(); } 

private: 
    QStack<gEntity*> clips; 
    static MyClipBoard* inst; 
}; 

CadgraphicsScene.cpp

MyClipBoard* MyClipBoard::inst = 0; 



    CadGraphicsScene::CadGraphicsScene(QObject *parent, QUndoStack *undoStack) 
     : QGraphicsScene(parent) 
    { 
     setFlags(); 
     id = 0; 
     mUndoStack = undoStack; 
     m_context = new QMenu; 
     m_context->addAction("Insert Circle"); 
     a_cut = m_context->addAction("cut"); 
     a_copy = m_context->addAction("copy"); 
     a_paste = m_context->addAction("paste"); 
     context_item = 0; 
     connect(m_context, SIGNAL(triggered(QAction*)), this, SLOT(contmenu(QAction*))); 

    } 
    void CadGraphicsScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){ 
     m_context->exec(event->screenPos()); 
    } 
    void CadGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) 
    { 
     // mousePressEvent in the graphicsScene 
     if(mouseEvent->button() == Qt::LeftButton) 
     { 
      switch (entityMode) 
      { 
      case NoMode: 
       qDebug() << "No Mode"; 
       break; 

      case PointMode: 
       pointItem = new Point(++id); 
       pointItem->setPos(mouseEvent->scenePos()); 
       itemList.append(pointItem); 
       mUndoStack->push(new CadCommandAdd(this, pointItem)); 
       break; 

      case LineMode: 
       if (mFirstClick) 
       { 
        start_p = mouseEvent->scenePos(); 
        mFirstClick = false; 
        mSecondClick = true; 
       } 

       else if (!mFirstClick && mSecondClick) 
       { 
        end_p = mouseEvent->scenePos(); 
        mPaintFlag = true; 
        mSecondClick = false; 
       } 

       if (mPaintFlag) 
       { 
        lineItem = new Line(++id, start_p, end_p); 
        lineItem->setLine(start_p.x(), start_p.y(), end_p.x(), end_p.y()); 
        itemList.append(lineItem); 
        mUndoStack->push(new CadCommandAdd(this, lineItem)); 
        setFlags(); 
       } 
       break; 

      case CircleMode: 
       if (mFirstClick) 
       { 
        start_p = mouseEvent->scenePos(); 
        mFirstClick = false; 
        mSecondClick = true; 
       } 

       else if (!mFirstClick && mSecondClick) 
       { 
        end_p = mouseEvent->scenePos(); 
        mPaintFlag = true; 
        mSecondClick = false; 
       } 

       if (mPaintFlag) 
       { 
        circleItem = new Circle(++id, start_p, end_p); 
        itemList.append(circleItem); 
        mUndoStack->push(new CadCommandAdd(this, circleItem)); 
        setFlags(); 
       } 
       break; 

      case EllipseMode: 
       if (mFirstClick) 
       { 
        start_p = mouseEvent->scenePos(); 
        mFirstClick = false; 
        mSecondClick = true; 
       } 

       else if (!mFirstClick && mSecondClick) 
       { 
        mid_p = mouseEvent->scenePos(); 
        mFirstClick = false; 
        mSecondClick = false; 
        mThirdClick = true; 
       } 

       else if (!mSecondClick && mThirdClick) 
       { 
        end_p = mouseEvent->scenePos(); 
        mThirdClick = false; 
        mPaintFlag = true; 
       } 

       if (mPaintFlag) 
       { 
        ellipseItem = new Ellipse(++id, start_p, mid_p, end_p); 
        itemList.append(ellipseItem); 
        mUndoStack->push(new CadCommandAdd(this, ellipseItem)); 
        setFlags(); 
       } 
       break; 

      case TextMode: 
       textItem = new mText(++id); 
       textItem->setPos(mouseEvent->scenePos()); 
       itemList.append(textItem); 
       textItem->setTextInteractionFlags(Qt::TextEditorInteraction); 
       mUndoStack->push(new CadCommandAdd(this, textItem)); 
       connect(textItem, SIGNAL(lostFocus(mText*)), 
         this, SLOT(editorLostFocus(mText*))); 
       connect(textItem, SIGNAL(selectedChange(QGraphicsItem*)), 
         this, SIGNAL(itemSelected(QGraphicsItem*))); 
       setFlags(); 

      default: 
       ; 
      } 
     }else if(event->button() & Qt::RightButton) 
      { 
       context_item = itemAt(event->scenePos().toPoint(), QTransform());//base operand not a pointer 
       cpos = event->scenePos();//says invalid use of member function 

       if(!context_item)//Here it says all variables out of scope 
       { 
        a_cut->setEnabled(false); 
        a_copy->setEnabled(false); 
        if(MyClipBoard::instance()->isempty()) 
         a_paste->setEnabled(false); 
        else a_paste->setEnabled(true); 
       } 
       else 
       { 
        a_cut->setEnabled(true); 
        a_copy->setEnabled(true); 
        a_paste->setEnabled(false); 
       } 
      } 



     QGraphicsScene::mousePressEvent(mouseEvent); 
    } 

cadgraphicsscene.h

private: 
QMenu* m_context; 
    QAction* a_cut; 
    QAction* a_copy; 
    QAction* a_paste; 
    QGraphicsItem* context_item; 
    QPointF cpos; 

回答

2

什麼你的意思切割grahicsitem的? (改變其位置或移動到另一個視圖)

用於複製和粘貼搜索在C克隆對象++不難,和粘貼只需更改新對象的位置,並添加到您的graphicsview或場景

更新:

#ifndef MYSCENE_H 
#define MYSCENE_H 

#include <QGraphicsView> 
#include <QGraphicsScene> 
#include <QGraphicsItem> 

#include <QGraphicsSceneContextMenuEvent> 

#include <QMenu> 
#include <QStack> 

class gEntity : public QObject, public QGraphicsItem 
{ 
public: 
    gEntity(QObject* parent=0) : QObject(parent) {} 
    virtual ~gEntity() {} 

    virtual gEntity* my_clone() { return 0; } 
}; 

class Circle : public gEntity 
{ 
public: 
    Circle(QObject* parent=0) : gEntity(parent) { 
     m_radius = 10; 
    } 

    qreal radius() const; 
    void setRadius(const qreal &radius); 

    gEntity* my_clone() 
    { 
     Circle* c = new Circle; 
     c->setRadius(m_radius); 
     return c; 
    } 

    QRectF boundingRect() const 
    { 
     return QRectF(-m_radius, -m_radius, 2 * m_radius, 2 * m_radius); 
    } 

    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) 
    { 
     painter->save(); 
     painter->setBrush(Qt::yellow); 
     painter->drawEllipse(QPointF(0,0), m_radius, m_radius); 
     painter->restore(); 
    } 

private: 
    qreal m_radius; 
}; 


class MyClipBoard 
{ 
public: 
    static MyClipBoard* instance() 
    { 
     if(!inst) 
      inst = new MyClipBoard; 
     return inst; 
    } 

    void push(gEntity* g) { 
     clips.push(g); 
    } 

    gEntity* last() 
    { 
     if(clips.count() == 0) return 0; 
     return clips.last(); 
    } 

    gEntity* pop() 
    { 
     if(clips.count() == 0) return 0; 
     return clips.pop(); 
    } 

    bool isempty() const { return clips.empty(); } 

private: 
    QStack<gEntity*> clips; 
    static MyClipBoard* inst; 
}; 

class MyScene : public QGraphicsScene 
{ 
    Q_OBJECT 
public: 
    MyScene(QObject* parent=0); 

    virtual ~MyScene() 
    { 
     delete m_context; 
    } 

protected: 
    void contextMenuEvent(QGraphicsSceneContextMenuEvent* event); 
    void mousePressEvent(QGraphicsSceneMouseEvent* event); 

public slots: 
    void insertCircle(const QPointF& pos) 
    { 
     Circle* mcircle = new Circle; 
     addItem(mcircle); 
     mcircle->setPos(pos); 
    } 

    void cut(gEntity* obj) 
    { 
     removeItem(obj); 
     MyClipBoard::instance()->push(obj); 
    } 

    void copy(gEntity* obj) 
    { 
     MyClipBoard::instance()->push(obj->my_clone()); 
    } 

    void paste(const QPointF& pos) 
    { 
     gEntity* last = MyClipBoard::instance()->pop(); 
     if(last) 
     { 
      addItem(last); 
      last->setPos(pos); 
     } 
    } 

    void contmenu(QAction* a) 
    { 
     if(a->text() == "Insert Circle") 
     { 
      insertCircle(cpos); 
     } 
     else if(a == a_cut) 
     { 
      cut(static_cast<gEntity*>(context_item)); 
     } 
     else if(a == a_copy) 
     { 
      copy(static_cast<gEntity*>(context_item)); 
     } 
     else if(a == a_paste) 
     { 
      paste(cpos); 
     } 
    } 

private: 
    QMenu* m_context; 
    QAction* a_cut; 
    QAction* a_copy; 
    QAction* a_paste; 
    QGraphicsItem* context_item; 
    QPointF cpos; 
}; 

#endif // MYSCENE_H 

scene.cpp

#include "myscene.h" 
#include <QGraphicsSceneMouseEvent> 

MyClipBoard* MyClipBoard::inst = 0; 

qreal Circle::radius() const 
{ 
    return m_radius; 
} 

void Circle::setRadius(const qreal &radius) 
{ 
    m_radius = radius; 
} 

MyScene::MyScene(QObject *parent) : QGraphicsScene(parent) 
{ 
    m_context = new QMenu; 
    m_context->addAction("Insert Circle"); 
    a_cut = m_context->addAction("cut"); 
    a_copy = m_context->addAction("copy"); 
    a_paste = m_context->addAction("paste"); 
    context_item = 0; 

    connect(m_context, SIGNAL(triggered(QAction*)), this, SLOT(contmenu(QAction*))); 
} 

void MyScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *event){ 
    m_context->exec(event->screenPos()); 
} 

void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *event) 
{ 
    QGraphicsScene::mousePressEvent(event); 

    if(event->button() & Qt::RightButton) 
    { 
     context_item = itemAt(event->scenePos().toPoint(), QTransform()); 
     cpos = event->scenePos(); 

     if(!context_item) 
     { 
      a_cut->setEnabled(false); 
      a_copy->setEnabled(false); 
      if(MyClipBoard::instance()->isempty()) 
       a_paste->setEnabled(false); 
      else a_paste->setEnabled(true); 
     } 
     else 
     { 
      a_cut->setEnabled(true); 
      a_copy->setEnabled(true); 
      a_paste->setEnabled(false); 
     } 
    } 
} 

的main.cpp

#include <QApplication> 

#include "myscene.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    QGraphicsView w(new MyScene); 
    w.setSceneRect(0,0,500,500); 
    w.show(); 

    return a.exec(); 
} 
+0

我收到很多錯誤:/檢查 – user3877872 2014-11-02 19:17:17

+0

讓我們[在聊天中繼續討論](http://chat.stackoverflow.com/rooms/64140/discussion-between-danics-and-user3877872)。 – danics 2014-11-02 21:50:31