Как ограничить область перетаскивания QGraphicsItem внутри QGraphicsScene

Рейтинг: 2Ответов: 1Опубликовано: 14.05.2023

я создаю небольшое приложение на Qt/C++ для работы с графическими элементами: оно представляет собой прямоугольную область, где можно перетаскивать объекты с помощью мыши, и вращать вокруг своей оси при помощи отдельного интерфейса.

Для того, чтобы объекты можно было перетаскивать мышью, при добавлении их на сцену, я устанавливаю флаг: setFlag(QGraphicsItem::ItemIsMovable) и это работает очень качественно.

В качестве контейнера для множества перемещаемых объектов выступает QGraphicsScene.

Но есть одна единственная проблема, которую я не могу решить - объект внутри сцены можно перетаскивать бесконечно далеко за пределы видимой области. setSceneRect() не помогает. Также я пробовал переопределять методы mousePressEvent() и mouseMoveEvent() и внутри них ограничивать перемещение, но тут проблема в том, что я теряю преимущества использования флага setFlag(QGraphicsItem::ItemIsMovable). Например при использовании флага, когда поворот объекта (вокруг своей оси) ненулевой его захват и перемещение работают все также корректно, а при переопределении мне так и не удалось нормально реализовать эти две функции. Также ограничение его перемещения по сцене при повороте объекта, работает очень криво.

Мне кажется очень странным то, что в Qt есть возможность использовать уже готовый функционал для перетаскивания объектов на сцене, но чтобы ограничить эту самую сцену, нужно переписывать весь этот функционал заново, хотя требование об ограничении сцены очень очевидное и нужное...

Поэтому возник вопрос - можно ли как-то ограничить область перетаскивания графических объектов внутри QGraphicsScene, и при этом сохранить использование флага QGraphicsItem::ItemIsMovable.

Ответы

▲ 1Принят

Допустим размер сцены 800x600.

P.S. размеры объекта сами высчитаете и досчитаете до центра.

Класс объекта от QGraphicsItem:

-добавь флаг на передвижение в конструктор

-добавь 2 переменные, куда сохраняешь позиции int oldX, oldY;

-добавь функции проверки выхода за границы сцены

bool observer_ward(int oldX, int oldY){
    if(oldX <= 800 && oldX >= 0 && oldY <= 600 && oldY >= 0)
        return true;
    else
        return false;
}

-добавь mouseMoveEvent(QGraphicsSceneEvent event)*

void mouseMoveEvent(QGraphicsSceneEvent* event){
    QPointF point = mapToScene(event->pos());
    if(observer_ward(point.x(), point.y())){//если не выходим за границы, то сохраняем каждую новую валидную в наши переменные
        oldX = point.x();
        oldY = point.y();
    }
    else{//если вышли за границы, то возвращаемся в последнюю валидную
        this->setPos(oldX, oldY);
    }
}