Russian Qt Forum
Сентябрь 30, 2024, 10:23 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: QGraphicsItem, boundingRect, hoverEvent - попадание в линию  (Прочитано 7173 раз)
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  линии А ....


Спасибо
Записан
ufna
Гость
« Ответ #1 : Август 04, 2010, 10:03 »

ну потому что линии делаются по другому О_о

а так - надо их переопределять и делать так, чтобы "срабатывали" когда надо, т.е. проверять вручную на линии такой или нет. Но линию "по диагонали" это имхо не верно.
Записан
ltise
Гость
« Ответ #2 : Август 04, 2010, 10:22 »

ну потому что линии делаются по другому О_о
сорри, по другому - это как ?

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

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

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

Записан
ufna
Гость
« Ответ #3 : Август 04, 2010, 11:14 »

ну есть такая вещь как поворот, поэтому линия делается горизонтальной, а затем поворачивается. В самом простом варианте для GV.

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

Посмотрю чего там за эвенты, чуть позже подскажу.
Записан
ltise
Гость
« Ответ #4 : Август 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 я даже намека на подобные проблемы не встречал Грустный
« Последнее редактирование: Август 04, 2010, 11:32 от ltise » Записан
kamre
Частый гость
***
Offline Offline

Сообщений: 233


Просмотр профиля
« Ответ #5 : Август 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():
Цитировать
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.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Август 04, 2010, 12:56 »

Находить расстояние от точки (позиции мыши) до отрезка (ов). Если оно меньше заданного - попали. Часто это минимальное расстояние называется aperture
Записан
ltise
Гость
« Ответ #7 : Август 05, 2010, 10:25 »


Вот что рисуется через QPainterPath, то и должно возвращаться в переопределенном методе 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.


Спасибо - то, что нужно, теперь все работает как надо Улыбающийся
Записан
ltise
Гость
« Ответ #8 : Август 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() помогло

Записан
ltise
Гость
« Ответ #9 : Август 05, 2010, 16:01 »


Тут сразу возник другой вопрос - как ловить события мыши, если указатель мыши находится не над элементом, а где-то там...сбоку ? т.е. если необходимо менять уровень подсветки элемента по мере приближения мыши к этому элементу..
желательно весь функционал убрать в элемент, т.е. химичить в QGraphicsScene нельзя...
Записан
mal
Гость
« Ответ #10 : Август 27, 2010, 10:22 »

если тебе не хочется "химичить" в сцене, то переопредели mouseMoveEvent сцены и распихивай из него координаты по айтемам, где уже и обрабатывай.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.07 секунд. Запросов: 23.