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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QGraphicsView и RubberBandDrag Поведение  (Прочитано 9972 раз)
EgorIvk
Гость
« : Апрель 02, 2009, 01:07 »

Здравствуйте ,
Подскажите пожалуйста как мне поступить. в Qt4 я новичек.
пытался найти решение моей проблемы везде ,но ни тут ,ни в гугле мало что нашел.
Точнее тут обсуждают ту же проблему но не дают решения :
http://lists.trolltech.com/qt4-preview-feedback/2006-08/thread00100-0.html

Суть в том что у меня есть в QGraphicsView на сцене очень много вплотную расположенных объектов(QGraphicsRectItem).
Мне нужно их как то выделить  с помощью мыши. Для этого я ставлю флаг setDragMod(QGraphicsView::RubberBandDrag).
Но проблема в том что RubberBand появляется только(!) когда точка нажатия мыши есть background , если попасть на item то ничего
не появится. Но в моем случае попасть на бэкгроунд почти нереально.
Каким образом можно заставить RubberBand появляться и поверх итемов?
Спасибо

Записан
mal
Гость
« Ответ #1 : Апрель 07, 2009, 11:06 »

Не знаю поможет ли вам это, но бы сделал так в аналогичном случае - создал QGraphicsRectItem - задал бы ему соответствующее перо
Код:
QPOint pt_click;
QGraphicsRectItem *rubber_rect_item;
...

rubber_rect_item = new QGraphicsRectItem();
rubber_rect_item->setVisible(false);

QPen rubber_pen;
rubber_pen.setColor(QColor(Qt::red));
rubber_pen.setWidth(2);
rubber_pen.setCapStyle(Qt::RoundCap);
rubber_pen.setStyle(Qt::DotLine);

rubber_rect_item->setRect(0,0,1,1);
rubber_rect_item->setVisible(false);
rubber_rect_item->setPen(rubber_pen);

далее по  левому лику мышки делаем
Код:
void CScene::mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent )
{

pt_click = mouseEvent->scenePos();
rubber_rect_item->setVisible(true);
}

и при движении мыши
Код:
void CScene::mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent )
{
QRectF rectF;
rectF.setBottomLeft(pt_click);
rectF.setTopRight(mouseEvent->scenePos());
QRectF norm_rect;
norm_rect = rectF.normalized();
rubber_rect_item->setRect(norm_rect);
}

Вот она ваша резинка ;-)

Осталось при отпускании левой кнопки мышки погасить рукотворную "резинку", взять ее координаты (BoundingRect) и посмотреть какие айтемы (item->boundingRect) на сцене он перекрывает.
Это тоже просто.

Может это и несколько громоздко, но работает.
Удачи.
Записан
BaltikS
Гость
« Ответ #2 : Апрель 07, 2009, 16:21 »

Мне кажется это немного не то, что хотел топикстартер.... К тому же в коде у Вас ошибка... При большом количестве итемов это добро (самопальный rubberBand) будет подтормаживать на сцене, да и нужно смотреть ещё contains и наверное ещё setSelected делать...
Записан
BaltikS
Гость
« Ответ #3 : Апрель 08, 2009, 06:28 »

Нашёл решение через "одно" место, но тем не менее...
1) Нужно всем итемам дать флаг setItemFlag(ItemIsSelectable,FALSE). Рубербанд уже будет работать, не реагируя на итемы.
2) Отслеживать на сцене клик мышью и передвижение мышью и отпускание мыши. Т.е. берём координаты прямоугольника РуберБанд;
3) Вычисляем вручную список всех итемов, которые вошли в этот прямоугольник;
4) В цикле принудительно им даюм флаг setFlag(ItemIsSelectable, TRUE). И тут же выделяем setSelected(TRUE).
Записан
mal
Гость
« Ответ #4 : Апрель 08, 2009, 07:20 »

BaltikS
проверил - стандартный rubberBand тормозит гораздо гораздее (!), чем такая самопальная реализация. Как бы вот. ;-)
С другой стороны, автор уже нашел решение.
Записан
BaltikS
Гость
« Ответ #5 : Апрель 08, 2009, 07:29 »

mal, Что то мне верится с трудом что он(Рубербанд) тормозит. Пример, 40000 чипов, ничего не тормозит. А при более сложной логике итемов, которых ещё и много, поверь мне, будет тормозить("самопальный" итем)... Я просто уже проверял.... Если автор темы уже решил эту задачу, то пусть поделится как. Мне например любопытно Улыбающийся...
« Последнее редактирование: Апрель 08, 2009, 07:31 от BaltikS » Записан
Khs
Гость
« Ответ #6 : Апрель 08, 2009, 07:51 »

+1, реализация rubberband через айтем плохая идея...
Записан
mal
Гость
« Ответ #7 : Апрель 08, 2009, 08:52 »

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

Пример с чипами для проверки производительности в данном случае не катит  - там куча айтемов с непересекающимися ректами. Там стандартный rubberBand отрабатывает быстро согласен.
В своем примере я имею  на сцене кучу полигонов с пересекающимися boundingRect'ами  - представь раскидистый куст. Плюс в каждом узле есть свой groupItem. BoundingRect'ы веток пересекаются. Размер сцены (на котором проверял скорость) )1300X1500 Плотность веток высокая. Смотри вложение. У меня на сцене в данном конкретном случае визуально стандартный rubberBand тормозит заметнее чем самопальный.  В замешательстве

Записан
BaltikS
Гость
« Ответ #8 : Апрель 08, 2009, 09:07 »

Может дело во флагах? ... Ну да ладно.....главное чтобы это дело удовлетворяло всех....а как оно реализовано - это уже на совести разработчика...
Записан
EgorIvk
Гость
« Ответ #9 : Май 17, 2009, 16:39 »

Всем большое спасибо за ответы =)
 долго на форум не заходил

Решил проблему просто :
Вместо QGraphicsScene и QGraphicsItem
Использовал для отображения объектов
QTableModel и QTableView
А там уже все эти выделения работают стандартно
Конечно мало кому такое подойдет =) но у меня работает
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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