Не изменяются координаты QGraphicsItem после перемещения

285
04 мая 2017, 15:35

Мне необходимо реализовать функцию масштабирования элементов QGraphicsItem на сцене. Я решил сделать это простым добавлением нового элемента, имеющим координаты старого, но умноженные на коэффициент высоту и ширину. Всё работает, как надо, если элемент просто добавляется на сцену, и сразу после этого я нажимаю на кнопку изменения масштаба. Но если же я это делаю после перемещения элемента, то новый добавляется с измененным размером, но в том месте, куда был изначально добавлен старый элемент, т.е. до перемещения. Элемент добавляю не статически. Вот как я это делаю.

void PaintScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if (mouseEvent->button() != Qt::LeftButton) //если нажали правую кнопку
    return;
 addItem(rect);
    Rect = new QGraphicsRectItem (QRectF());
    Rect->setPen(QPen(Qt::darkCyan, 3));
    addItem(Rect);
    m_isKeyPressed=true;
    x_old = mouseEvent->scenePos().x();
    y_old=mouseEvent->scenePos().y();
 }
 void PaintScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
 {
  if (m_isKeyPressed)
    {
        int X, Y, Xmin, Ymin;
        X = qMax(mouseEvent->scenePos().x(), x_old);
                                    Y = qMax(mouseEvent->scenePos().y(), y_old);
                                    Xmin = qMin(mouseEvent->scenePos().x(), x_old);
                                    Ymin = qMin(mouseEvent->scenePos().y(), y_old);
                                    QRectF newRect (Xmin, Ymin, X-Xmin, Y-Ymin);
                                    Rect->setRect(newRect);
                                    Rect-   >setFlag(QGraphicsRectItem::ItemIsMovable, true);
                                    Rect->setFlag(QGraphicsRectItem::ItemIsSelectable, true);
    }
}
void PaintScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
 if (mouseEvent->button() == Qt::LeftButton)
    {
        update();
        m_isKeyPressed = false;
    }
 }

Так я создаю новый элемент, который должен замещать старый.

bool PaintScene::scaleObject(const qreal Scala)
{
foreach (QGraphicsItem *item, selectedItems()){
 QPointF point1 = item->boundingRect().topLeft();
    QPointF point2 = item->boundingRect().bottomRight();
    Angle = item->data(key_angle).toDouble();
    rect = new QGraphicsRectItem();
    addItem(rect);
    rect->setPen(QPen(Qt::darkRed, 3));
    //rect->setRect(point1.x(), point1.y(),(point2.x()-point1.x())*Scala, (point2.y()-point1.y())*Scala);
    rect->setRect(point1.x(), point1.y(), (point2.x()-point1.x())*Scala, (point2.y()-point1.y())*Scala);
    //rect->setPos(0, 0); 
    removeItem(item);
    if (Angle)
    {
        QTransform Transf = rect->transform();
                QPointF p = item->boundingRect().center();

                Transf.translate(p.x(), p.y());
                Transf.rotate(Angle);
                Transf *= QTransform::fromScale(rect->scale(),rect->scale());
                Transf.translate(-p.x(),  -p.y());
                //QPointF point;
                //point = rect->scenePos();
                rect->setTransform(Transf);
                rect->setData(key_angle, Angle);
                //rect->setPos(point.x(), point.y());
   }
    rect->setFlag(QGraphicsRectItem::ItemIsMovable, true);
    rect->setFlag(QGraphicsRectItem::ItemIsSelectable, true);
    rect->update();
    update();
    clearSelection();
        }return true;
}

Подкиньте какие-нибудь идеи, пожалуйста. Главный вопрос, почему не сохраняются координаты QGraphicsItem'ов после перемещения. Или я чего-то не понимаю? Спасибо.

Answer 1

Создаём квадраты на сцене нажатием правой кнопки мыши, перемещаем их при помощи зажатой левой кнопки мыши, выделенный квадрат после нажатия клавиши '+' единожды увеличивается в размере в два раза.

#ifndef MAINWIN_H
#define MAINWIN_H
#include <QtWidgets/QMainWindow>
#include <QGraphicsView>
#include <QGraphicsObject>
#include <QKeyEvent>
#include <QGraphicsSceneMouseEvent>
class CustomScene : public QGraphicsScene
{
public:
    void mousePressEvent(QGraphicsSceneMouseEvent *_ev) override
    {
        if (_ev->button() == Qt::RightButton)
        {
            QGraphicsRectItem* rect = new QGraphicsRectItem(QRectF(0, 0, 50, 50));
            rect->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable);
            addItem(rect);
            rect->setPos(_ev->scenePos());
        }
        QGraphicsScene::mousePressEvent(_ev);
    }
    void keyPressEvent(QKeyEvent *_ev)
    {
        if (_ev->key() == Qt::Key::Key_Plus)
        {
            qreal scale = 2;
            foreach(QGraphicsItem *item, selectedItems())
            {
                item->setScale(scale);
                item->update();
            }
        }
        QGraphicsScene::keyPressEvent(_ev);
    }
};
class mainwin : public QMainWindow
{
    Q_OBJECT
public:
    mainwin(QWidget *parent = 0)
    {
        QGraphicsView* view_widget = new QGraphicsView();        
        CustomScene* scene = new CustomScene();
        scene->setSceneRect(view_widget->rect());
        view_widget->setScene(scene);
        setCentralWidget(view_widget);
        setFixedSize(640, 480);
    }
};
#endif // MAINWIN_H
READ ALSO
Наследование шаблонов

Наследование шаблонов

Почему не работает следующий код?

186
SFINAE не работает :(

SFINAE не работает :(

Почему не компилируется?

223
Как пользоваться QJsonDocument

Как пользоваться QJsonDocument

Подскажите пожалуйста как пользоваться QJsonDocumentЯ cделал запрос на сервер

463
C++ Парсинг строки

C++ Парсинг строки

Привет всемЕсть строка с аргументами к примеру "Привет, меня зовут %1, мне %2 лет

418