Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: Achernar от Декабрь 12, 2013, 08:54



Название: Линия с маркерами
Отправлено: Achernar от Декабрь 12, 2013, 08:54
Здраствуйте!

Пробую сделать линию с маркерами, с помощью которых можно менять точки.
Код:
void Line::hoverEnterEvent(QGraphicsSceneHoverEvent *)
{
firstPointGrabber = new LineGrabber(this);
    firstPointGrabber->setPos(QPointF(line().p1().x() - firstPointGrabber->getWidth() / 2, line().p1().y() - firstPointGrabber->getWidth() / 2));
firstPointGrabber->installSceneEventFilter(this);

secondPointGrabber = new LineGrabber(this);
    secondPointGrabber->setPos(QPointF(line().p2().x() - secondPointGrabber->getWidth() / 2, line().p2().y() - secondPointGrabber->getWidth() / 2));
    secondPointGrabber->installSceneEventFilter(this);
}

В hoverEnterEvent создаю два маркера,

Код:
void Line::hoverLeaveEvent(QGraphicsSceneHoverEvent *)
{
firstPointGrabber->setParentItem(0);
secondPointGrabber->setParentItem(0);

delete firstPointGrabber;
delete secondPointGrabber;
}

в hoverLeaveEvent удаляю.

Код:
bool Line::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
{
LineGrabber *lineGrabber = dynamic_cast<LineGrabber *>(watched);

if(lineGrabber == 0)
return false;

QGraphicsSceneMouseEvent *mouseEvent = dynamic_cast<QGraphicsSceneMouseEvent *>(event);

if(mouseEvent == 0)
return false;   

switch(mouseEvent->type())
{
case QEvent::GraphicsSceneMousePress:
{
lineGrabber->setMode(LineGrabber::m_press);
firstPointGrabber->setPoint(line().p1());
secondPointGrabber->setPoint(line().p2());
    }

break;

case QEvent::GraphicsSceneMouseRelease:
{
lineGrabber->setMode(LineGrabber::m_release);


    }
break;

case QEvent::GraphicsSceneMouseMove:
{
lineGrabber->setMode(LineGrabber::m_move);
}

break;

default:
return false;
}

    if(lineGrabber->getMode() == LineGrabber::m_move)
    {
        if(lineGrabber == firstPointGrabber)
        {
            setLine(QLineF(mouseEvent->scenePos(), secondPointGrabber->getPoint()));
            firstPointGrabber->setPos(mouseEvent->scenePos().x() - firstPointGrabber->getWidth() / 2, mouseEvent->scenePos().y() - firstPointGrabber->getWidth() / 2);
        }

        else
        {
            setLine(QLineF(firstPointGrabber->getPoint(),mouseEvent->scenePos()));
            secondPointGrabber->setPos(mouseEvent->scenePos().x() - secondPointGrabber->getWidth() / 2, mouseEvent->scenePos().y() - secondPointGrabber->getWidth() / 2);
        }
    }

return true;
}

В sceneEventFilter отлавливаю событие нажатие, сохраняю начальные точки в маркерах и двигаю первую или вторую точку.

Пока линия находится на текущем месте работает все как надо, но если линию передвинуть, то получаются какие-то расстояния между точками и мышью, судя по всему проблемы с системой координат.




Название: Re: Линия с маркерами
Отправлено: Achernar от Декабрь 13, 2013, 06:33
Переформулирую вопрос:

В сцену добавляем линию, как я понимаю в этом случае совпадают координаты линии относительно сцены и собственные координаты и перемещаю один из концов:

Код:
setLine(QLine(event->scenePos(), line().p2()));

Работает правильно.

Теперь перемещаю линию мышью, меняются координаты относительно сцены и работает не так, как надо.

Как правильно задать координаты в этом случае?


Название: Re: Линия с маркерами
Отправлено: Fregloin от Декабрь 13, 2013, 10:01
могу дать свою реализацию, но она довольно сложна и в вырезаном виде врядли будет работать. суть в том, что для редактирования такой полигональной линии с маркерами у меня создается отдальный элемент-редактор, который рисуется над этой линией и в своих событиях мыши оперирует анкерами(маркерами) редактроуемого объекта.


Название: Re: Линия с маркерами
Отправлено: Achernar от Декабрь 13, 2013, 10:11
Мне бы попроще, хотелось обрабатывать прямо из объекта, но с координатами никак не могу разобраться.


Название: Re: Линия с маркерами
Отправлено: Fregloin от Декабрь 16, 2013, 16:28
Как показала практика лучше сделать отдельный редактор маркеров, нежели их обрабатывать в самом объекте. По крайней мере если таких объектов много.