Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: ltise от Август 04, 2010, 09:55



Название: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: ltise от Август 04, 2010, 09:55
Все привет!

Возник вопрос:
есть объект, потомок QGraphicsItem подобный линии, например [0,0] - [100,100]
переопределяю метод

   QRectF boundingRect() const
   {
      return QRectF(0,0,100,100);
   }

в дальнейшем использую методы hoveMouseXXX

Вопрос - как сделать так, чтобы методы hoveMouseXXX срабатывали только при попадании в область линии, а не в ограничивающий линию прямоугольник ?

Например если есть 2 близко расположенные линии
A([0,0] - [100,100]) и B([10,10] - [90, 90]) то попасть в линию B, расположенную под A - нереально,т.к. boundingRect B расположен под  boundingRect  линии А ....


Спасибо


Название: Re: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: ufna от Август 04, 2010, 10:03
ну потому что линии делаются по другому О_о

а так - надо их переопределять и делать так, чтобы "срабатывали" когда надо, т.е. проверять вручную на линии такой или нет. Но линию "по диагонали" это имхо не верно.


Название: Re: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: ltise от Август 04, 2010, 10:22
ну потому что линии делаются по другому О_о
сорри, по другому - это как ?

могут быть под любым углом,
но вообще не совсем линии, линия - это упрощенный пример

а так - надо их переопределять и делать так, чтобы "срабатывали" когда надо, т.е. проверять вручную на линии такой или нет. Но линию "по диагонали" это имхо не верно.

иными словами отказаться от hoverMouse методов, и где-то перебирать объекты сцены (под мышью) ?



Название: Re: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: ufna от Август 04, 2010, 11:14
ну есть такая вещь как поворот, поэтому линия делается горизонтальной, а затем поворачивается. В самом простом варианте для GV.

А так - я не в курсе что счас за методы, с GV работал когда их еще не было, но обычная практика такая - вначале гоним по boundingRect'ам, а среди найденных - уже смотрим "попало ли на линию".

Посмотрю чего там за эвенты, чуть позже подскажу.


Название: Re: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: ltise от Август 04, 2010, 11:30
ну есть такая вещь как поворот, поэтому линия делается горизонтальной, а затем поворачивается. В самом простом варианте для GV.


Так  и делаю:

Код:
	void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
.......              


float c = 180*angleAt(_x0, _y0)/M_PI;
painter->rotate(c);

.......              

QPainterPath path;
p1.addRect(0, 0, width, height);
painter->drawPath(path);

.......              
        }

Цитировать
А так - я не в курсе что счас за методы, с GV работал когда их еще не было, но обычная практика такая - вначале гоним по boundingRect'ам, а среди найденных - уже смотрим "попало ли на линию".


хотелось бы  использовать максимально имеющиеся возможности ...
если нельзя, то придется самому конечно "бегать"...
хотя странно, во Flex AS3 я даже намека на подобные проблемы не встречал :(


Название: Re: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: kamre от Август 04, 2010, 12:18
Так  и делаю:

Код:
	void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
.......              
QPainterPath path;
p1.addRect(0, 0, width, height);
painter->drawPath(path);
.......              
        }
Вот что рисуется через QPainterPath, то и должно возвращаться в переопределенном методе shape() (http://doc.qt.nokia.com/latest/qgraphicsitem.html#shape):
Цитировать
Returns the shape of this item as a QPainterPath in local coordinates. The shape is used for many things, including collision detection, hit tests, and for the QGraphicsScene::items() functions.

The default implementation calls boundingRect() to return a simple rectangular shape, but subclasses can reimplement this function to return a more accurate shape for non-rectangular items. For example, a round item may choose to return an elliptic shape for better collision detection.


Название: Re: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: Igors от Август 04, 2010, 12:56
Находить расстояние от точки (позиции мыши) до отрезка (ов). Если оно меньше заданного - попали. Часто это минимальное расстояние называется aperture


Название: Re: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: ltise от Август 05, 2010, 10:25

Вот что рисуется через QPainterPath, то и должно возвращаться в переопределенном методе shape() (http://doc.qt.nokia.com/latest/qgraphicsitem.html#shape):
Цитировать
Returns the shape of this item as a QPainterPath in local coordinates. The shape is used for many things, including collision detection, hit tests, and for the QGraphicsScene::items() functions.


Спасибо - то, что нужно, теперь все работает как надо :)


Название: Re: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: ltise от Август 05, 2010, 14:42
Находить расстояние от точки (позиции мыши) до отрезка (ов). Если оно меньше заданного - попали. Часто это минимальное расстояние называется aperture

Так и делаю:
Код:
	bool contains(const QPointF &p) const
{
return pointIntesectLine(_x0, _y0, 0, 0, p.x(), p.y(), 1);
}

Проблема была в том, что событие hoverEvent срабатывало по boundRect...использование shape() помогло



Название: Re: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: ltise от Август 05, 2010, 16:01

Тут сразу возник другой вопрос - как ловить события мыши, если указатель мыши находится не над элементом, а где-то там...сбоку ? т.е. если необходимо менять уровень подсветки элемента по мере приближения мыши к этому элементу..
желательно весь функционал убрать в элемент, т.е. химичить в QGraphicsScene нельзя...


Название: Re: QGraphicsItem, boundingRect, hoverEvent - попадание в линию
Отправлено: mal от Август 27, 2010, 10:22
если тебе не хочется "химичить" в сцене, то переопредели mouseMoveEvent сцены и распихивай из него координаты по айтемам, где уже и обрабатывай.