Название: (РЕШЕНО) Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 04, 2015, 12:51 Мне надо ловить события при наведении на нарисованные с помощью setLine(...) соединительные линии. Линии могут идти под разными углами. Еще не начинал делать, поскольку не ясно как именно. Насколько я понимаю, boundingRect() вокруг линии, проведенной под углом - это будет прямоугольник, у которого линия является диагональю. То есть, если просто в классе, наследующем QGraphicsLineItem переопределить hoverEnterEvent(...), то ловиться будет по всей сцене, если линию провести от угла до угла сцены.
Или нет? Или как сделать, чтобы курсор ловился только на линии, и причем с возможностью задать ширину зоны захвата? Просто именно такие вопросы еще ни разу не решал, тем более с Qt, поэтому не вполне ясно, как с его средствами это реализовывать. Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Bepec от Февраль 04, 2015, 13:11 Помнится была темка с похожим вопросом - как линию поймать. Но вроде так до конца и не разобрались - ховеревент и проверка принадлежности пикселя к линии не подходят - слишком большая погрешность.
Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Igors от Февраль 04, 2015, 16:07 Посчитать расстояние от точки до отрезка
Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 04, 2015, 16:21 Посчитать расстояние от точки до отрезка Где? В приемнике hoverEnterEvent(...)? Теперь представим себе, что линий дофига, и их boundingRect перекрываются. Все приёмники будут дружно и совершенно бесполезно считать эти расстояния. И еще придется нудно со всеми разбираться, кто выше, кто ниже. Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Old от Февраль 04, 2015, 16:26 Теперь представим себе, что линий дофига, и их boundingRect перекрываются. Все приёмники будут дружно и совершенно бесполезно считать эти расстояния. И еще придется нудно со всеми разбираться, кто выше, кто ниже. А вы ждете, что Qt это чудесным образом решит? Кто-то все это должен будет сделать. :)Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 04, 2015, 16:32 Теперь представим себе, что линий дофига, и их boundingRect перекрываются. Все приёмники будут дружно и совершенно бесполезно считать эти расстояния. И еще придется нудно со всеми разбираться, кто выше, кто ниже. А вы ждете, что Qt это чудесным образом решит? Кто-то все это должен будет сделать. :)Это само собой. Но если просчитывать все boundingRect, то практически любое перемещение курсора будет вызывать кучу этих по идее ненужных действий. То есть, оно всё надо, но только когда курсор оказывается вблизи линии. Попутно любопытно стало - а сильно бы просела производительность всей этой графической иерархии, если бы у boundingRect имелся бы еще и угол поворота. Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Igors от Февраль 04, 2015, 16:52 Где? В приемнике hoverEnterEvent(...)? Теперь представим себе, что линий дофига, и их boundingRect перекрываются. Все приёмники будут дружно и совершенно бесполезно считать эти расстояния. И еще придется нудно со всеми разбираться, кто выше, кто ниже. В mouseMoveEvent. Если нужно - определить какой айтем(ы) под мышей. Если "дофига" < 100, то расходы смешные. Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 04, 2015, 17:06 Где? В приемнике hoverEnterEvent(...)? Теперь представим себе, что линий дофига, и их boundingRect перекрываются. Все приёмники будут дружно и совершенно бесполезно считать эти расстояния. И еще придется нудно со всеми разбираться, кто выше, кто ниже. В mouseMoveEvent. Если нужно - определить какой айтем(ы) под мышей. Если "дофига" < 100, то расходы смешные. Хех... Так оно же определяет какой айтем под мышей именно по boundingRect айтемов, чего для линий делать не имеет смысла. То есть, это означает, что надо заводить собственный реестр только для линий, и на каждом движении мыши проверять не находится ли курсор над точкой какой-либо из них +- 2 точки в стороны перепендикулярно линии. И еще при этом обработать перекрытия линий. Вау... Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Igors от Февраль 04, 2015, 17:22 Хех... Так оно же определяет какой айтем под мышей именно по boundingRect айтемов, чего для линий делать не имеет смысла. То есть, это означает, что надо заводить собственный реестр только для линий, и на каждом движении мыши проверять не находится ли курсор над точкой какой-либо из них +- 2 точки в стороны перепендикулярно линии. И еще при этом обработать перекрытия линий. Вау... Какой "реестр" - метод items вернет список всех, отсекаете "нелинии" напр с помощью qobject_cast. И какое там "вау" - это банальная задача для первокурсника.Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Bepec от Февраль 04, 2015, 17:38 Нуу я бы так не сказал. Но вдруг Igors прав, попробуйте )
Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 04, 2015, 17:40 Хех... Так оно же определяет какой айтем под мышей именно по boundingRect айтемов, чего для линий делать не имеет смысла. То есть, это означает, что надо заводить собственный реестр только для линий, и на каждом движении мыши проверять не находится ли курсор над точкой какой-либо из них +- 2 точки в стороны перепендикулярно линии. И еще при этом обработать перекрытия линий. Вау... Какой "реестр" - метод items вернет список всех, отсекаете "нелинии" напр с помощью qobject_cast. И какое там "вау" - это банальная задача для первокурсника.Для первокурсника - может быть. ;D Я когда-то на первом курсе любые интегралы щелкал, как сёмочки... Не, понятно, что всё это можно сделать, но как бы... при таком мощном фреймворке проделывать вручную некие нижнеуровневые вычисления, которые должны быть у него в комплекте. :-\ Собственно items() с отсечкой не-линий, этот реестр и вернёт. Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Igors от Февраль 04, 2015, 18:00 ... при таком мощном фреймворке проделывать вручную некие нижнеуровневые вычисления, которые должны быть у него в комплекте. :-\ Так откуда он может знать до каких линий считать? Если нужна ф-ция для вычисления расстояния - завтра напишу (сейчас ухожу). Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 04, 2015, 18:07 Спс. Это я и сам могу написать, элементарная геометрия. Просто это наверняка в потрохах есть. Вполне могло бы быть доступно, например, как метод класса QGraphicsLineItem. Там есть какой-то bool QGraphicsLineItem::contains ( const QPointF & point ), но пока не разобрался, как именно он работает.
Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 06, 2015, 00:08 Хм... А ведь линия отзывается на мышь не в таком boundingRect, как я думал.
Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Old от Февраль 06, 2015, 03:49 Хм... А ведь линия отзывается на мышь не в таком boundingRect, как я думал. В методе:QPainterPath QGraphicsItem::shape () const [virtual] можно более детельно описать форму объекта. Фигура проверяется уже после положительной проверки на бокс. Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Igors от Февраль 06, 2015, 10:02 Можно установить нужную толщину (напр 2*2 = 4) и проверить получается ли нужный захват. Если да то перекрыть paint где рисовать своим pen'ом. Впрочем расстояния до отрезка это не даст.
Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 06, 2015, 12:59 Хм... А ведь линия отзывается на мышь не в таком boundingRect, как я думал. В методе:QPainterPath QGraphicsItem::shape () const [virtual] можно более детельно описать форму объекта. Фигура проверяется уже после положительной проверки на бокс. Очевидно это и сделано по-умолчанию для линий. Методы hoverEnterEvent() и hoverLeaveEvent() срабатывают на расстоянии 2 пиксела от линии (я вычислил расстояние и вывел его в qDebug() в этих методах), под любым её углом и при любом направлении. То есть, в случае линий не надо сканировать айтемы на сцене в поисках линий, не надо переопределять boundingBox(), вообще ничего не надо делать, кроме переопределения hoverEnterEvent(), hoverLeaveEvent() и аналогичных методов, в которых делается всё, что требуется. В документации об этом ни слова. Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: GreatSnake от Февраль 06, 2015, 13:11 В документации об этом ни слова. Цитата: assistant void QGraphicsItem::hoverEnterEvent ( QGraphicsSceneHoverEvent * event ) [virtual protected] А это что ???This event handler, for event event, can be reimplemented to receive hover enter events for this item. The default implementation calls update(); otherwise it does nothing. И не проще ли было сразу взять и попробовать ??? Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 06, 2015, 13:22 В документации об этом ни слова. Цитата: assistant void QGraphicsItem::hoverEnterEvent ( QGraphicsSceneHoverEvent * event ) [virtual protected] А это что ???This event handler, for event event, can be reimplemented to receive hover enter events for this item. The default implementation calls update(); otherwise it does nothing. А это не то совершенно. Переводится с английского так - "умолчательная реализация вызывает update()", update() - это перерисовка айтема. Тут речь была об определении факта приближения к линии, что к перерисовке не имеет никакого отношения. И не проще ли было сразу взять и попробовать ??? Нет. Чтобы попробовать, пришлось написать функцию вычисления расстояния до линии от точки на плоскости. Спросить в форуме изначально гораздо проще. Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: GreatSnake от Февраль 06, 2015, 13:29 Данный метод будет вызван только при QGraphicsItem::setAcceptHoverEvents( true ), в описании которой всё сказано:
Цитата: assistant If enabled is true, this item will accept hover events; otherwise, it will ignore them. By default, items do not accept hover events. Hover events are delivered when there is no current mouse grabber item. They are sent when the mouse cursor enters an item, when it moves around inside the item, and when the cursor leaves an item. Hover events are commonly used to highlight an item when it's entered, and for tracking the mouse cursor as it hovers over the item (equivalent to QWidget::mouseTracking). Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Igors от Февраль 06, 2015, 13:59 Нет. Чтобы попробовать, пришлось написать функцию вычисления расстояния до линии от точки на плоскости. Ну отдыхайте, наверное очень устали от такой сложной задачи :)Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 06, 2015, 14:03 Данный метод будет вызван только при QGraphicsItem::setAcceptHoverEvents( true ), в описании которой всё сказано: Цитата: assistant If enabled is true, this item will accept hover events; otherwise, it will ignore them. By default, items do not accept hover events. Hover events are delivered when there is no current mouse grabber item. They are sent when the mouse cursor enters an item, when it moves around inside the item, and when the cursor leaves an item. Hover events are commonly used to highlight an item when it's entered, and for tracking the mouse cursor as it hovers over the item (equivalent to QWidget::mouseTracking). А тут сказано только, что этот метод включает и выключает прием событий hover. Но ничего не сказано где по отношению к айтему эти события генерятся, когда включены. По-умолчанию где определяется с помощью boundingRect(). В случае линии, это уже не так, очевидно используется shape(). А об этом нет нигде ни слова. Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 06, 2015, 14:03 Нет. Чтобы попробовать, пришлось написать функцию вычисления расстояния до линии от точки на плоскости. Ну отдыхайте, наверное очень устали от такой сложной задачи :)Минут 30 заняло. Написать в форум - меньше минуты. ;D Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Igors от Февраль 06, 2015, 14:32 Минут 30 заняло. Написать в форум - меньше минуты. ;D Плюс дождаться ответа, выразить справедливое возмущение бестолковыми советами, написать еще, уточнить и.т.п. :)Название: Re: Событие при наведении на QGraphicsLineItem Отправлено: Гурман от Февраль 06, 2015, 16:11 Минут 30 заняло. Написать в форум - меньше минуты. ;D Плюс дождаться ответа, выразить справедливое возмущение бестолковыми советами, написать еще, уточнить и.т.п. :)В ожидании ответа другие вещи делаются (у меня в ToDo list еще больше сотни позиций). Всё остальное - секунды. 180 символов в минуту десятипальцевый слепой набор. ;D В форум заглянуть и ответы проверить - это вместо перекура, давно бросил. А отдыхать несомненно надо. Обязательно. Сегодня пятница. Водка уже стынет в морозилке. Куриные котлеты в ореховой панировке по-турецки жарятся на плите... :P |