Как ограничить область перетаскивания QGraphicsItem внутри QGraphicsScene
я создаю небольшое приложение на 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);
}
}