在图形视图中剪切复制粘贴

Cut copy paste in Graphics View

本文关键字:复制 图形 视图      更新时间:2023-10-16

我有5个实体,可以在鼠标事件和按钮点击的图形视图中添加。每个实体都被分配了唯一的id。我需要添加剪切、复制和粘贴操作这些实体。如何进行。在Qt的图形视图中,我没有得到任何剪切、复制粘贴操作的例子。我该怎么做?

我对所有实体都有不同的类,我的类直线、圆和椭圆继承自QGraphicsItem,直线和文本继承自QgraphicsLineItem和QgraphicsEllipse Item。请告诉我怎样才能和他们一起工作。line.cpp

#include "line.h"
Line::Line(int i, QPointF p1, QPointF p2)
{
    // assigns id
    id = i;
    // set values of start point and end point of line
    startP = p1;
    endP = p2;
}
int Line::type() const
{
    // Enable the use of qgraphicsitem_cast with line item.
    return Type;
}
QRectF Line::boundingRect() const
{
    qreal extra = 1.0;
    // bounding rectangle for line
    return QRectF(line().p1(), QSizeF(line().p2().x() - line().p1().x(),
                                      line().p2().y() - line().p1().y()))
            .normalized()
            .adjusted(-extra, -extra, extra, extra);
}
void Line::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                  QWidget *widget)
{
    // draws/paints the path of line
    QPen paintpen;
    painter->setRenderHint(QPainter::Antialiasing);
    paintpen.setWidth(1);
    if (isSelected())
    {
        // sets brush for end points
        painter->setBrush(Qt::SolidPattern);
        paintpen.setColor(Qt::red);
        painter->setPen(paintpen);
        painter->drawEllipse(startP, 2, 2);
        painter->drawEllipse(endP, 2, 2);
        // sets pen for line path
        paintpen.setStyle(Qt::DashLine);
        paintpen.setColor(Qt::black);
        painter->setPen(paintpen);
        painter->drawLine(startP, endP);
    }
    else
    {
        painter->setBrush(Qt::SolidPattern);
        paintpen.setColor(Qt::black);
        painter->setPen(paintpen);
        painter->drawEllipse(startP, 2, 2);
        painter->drawEllipse(endP, 2, 2);
        painter->drawLine(startP, endP);
    }
}

如何使用此QGraphicsLineItem?

我认为您应该使用自定义图形场景。创建QGraphicsScene子类。重新实现按键事件:

if (e->key() == Qt::Key_C && e->modifiers() & Qt::ControlModifier)
{
           listCopiedItems =  this->selectedItems();
}
 
 
if (e->key() == Qt::Key_V && e->modifiers() & Qt::ControlModifier)
{
           for(int i=0; i< listCopiedItems.count(); i++)
           {
              //create new objects, set position and properties 
           }
}

您可以从旧对象中获取所有需要的属性,如颜色、大小等,并将其设置为新属性。对于剪切,做同样的事情,但从场景中删除旧对象,当所有工作都完成时,从内存中删除这些对象。还可以使用QShortcut类创建快捷方式。

编辑。我想说的是,这是一项非常复杂的任务,所以我不能为您提供所有情况、所有类型的代码。我只举了一个例子,但这个例子有效(我测试了它)。我在这里发布了绝对完整的代码。

标题:

#ifndef GRAPHICSSCENE_H
#define GRAPHICSSCENE_H
#include <QGraphicsScene>
#include <QStack>
#include <QPoint>
#include <QMouseEvent>
class GraphicsScene : public QGraphicsScene
{
    Q_OBJECT
public:
    explicit GraphicsScene(QObject *parent = 0);
signals:
protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);
public slots:
    private:
    QList<QGraphicsItem *> lst; QPoint last;
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    QVector<QGraphicsEllipseItem * > vec;
    };
#endif // GRAPHICSSCENE_H

Cpp:

#include "graphicsscene.h"
#include <QDebug>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsItem>
GraphicsScene::GraphicsScene(QObject *parent) :
    QGraphicsScene(parent)
{
//add something
addPixmap(QPixmap("G:/2/qt.jpg"));
vec.push_back(addEllipse(0,0,50,50,QPen(Qt::red),QBrush(Qt::blue)));
vec.push_back(addEllipse(0+100,0+100,50,50,QPen(Qt::red),QBrush(Qt::blue)));
vec.push_back(addEllipse(0+150,0+150,50,50,QPen(Qt::red),QBrush(Qt::blue)));
}
void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    //qDebug() << "in";
    if (mouseEvent->button() == Qt::LeftButton)
    {
        last = mouseEvent->scenePos().toPoint();//remember this point, we need it for copying
        QGraphicsItem *item = itemAt(mouseEvent->scenePos(), QTransform());
        item->setFlags(QGraphicsItem::ItemIsSelectable);
        item->setSelected(!item->isSelected());
    }
    QGraphicsScene::mousePressEvent(mouseEvent);
}
void GraphicsScene::keyPressEvent(QKeyEvent *e)
{
    if (e->key() == Qt::Key_C && e->modifiers() & Qt::ControlModifier)
    {
        lst = this->selectedItems();
    }
    if (e->key() == Qt::Key_V && e->modifiers() & Qt::ControlModifier)
    {
               for(int i=0; i< lst.count(); i++)
               {
                  //if it is ellipse
                   QGraphicsEllipseItem *ell = qgraphicsitem_cast<QGraphicsEllipseItem *>(lst.at(i));
                   if(ell)
                   {//then add ellipse to scene with ell properties and new position
                        addEllipse(QRect(last,ell->rect().size().toSize()),ell->pen(),ell->brush());
                           qDebug() << "good";
                   }
               }
    }

    QGraphicsScene::keyPressEvent(e);
}

它非常复杂,因为并没有任何clone()方法,所以无法克隆具有所有属性的对象并将其移动到新位置。如果你有你的具体项目,你也应该提供一些具体的东西。这就是为什么它很复杂,而且我无法获得所有情况的代码。

编辑

你不能显示场景,你应该使用这个代替:

QGraphicsView vview;
GraphicsScene ss;
vview.setScene(&ss);
vview.show();