Reputation: 817
I have different subclasses for my entities. The entities are drawn in GraphicsView, How can apply the Clipboard operations for Cut, Copy and Paste.
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;
Upvotes: 0
Views: 490
Reputation: 323
what are you mean of cutting a grahicsitem? (change its position or move to another view)
for copy and paste search for cloning a object in c++ it's not hard, and in paste just change position of new object and add that to your graphicsview or scene
update:
#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();
}
Upvotes: 2