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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Перегрузка QGraphicsView, не отображаются элементы сцены  (Прочитано 10445 раз)
elive
Гость
« : Март 24, 2010, 09:32 »

 Приветствую. Возникла следующая проблема. У меня имеется класс, наследованный от QGraphicsView, к которому я прикрутил рисование мышкой, то есть перегрузил paintEvent. Так же мне необходимо в данный класс добавить сцену, содержащие айтемы. Но после перегрузки, элементы сцены не отображаются, отображается лишь то, что я рисую в QGraphicsView.

Исходная задача у меня такая: при нажатии на айтем, мне необходимо производить рисование. Если рисовать в самом айтеме, то необходимо создавать boundingRect, размером со всю сцену, производительность при этом сильно просидает. Поэтому хочу передавать рисование в QGraphicsView.
Записан
alexman
Гость
« Ответ #1 : Март 24, 2010, 09:40 »

А если рассмотреть линию, которую ресуешь, как item?
Записан
elive
Гость
« Ответ #2 : Март 24, 2010, 09:57 »

А если рассмотреть линию, которую ресуешь, как item?
Во втором абзаце я написал, что при таком раскладе сильно падает производительность. + Рисую не обязательно линию, может быть любая траектория.
 Хотя если предложишь, как это реализовать, например через path, чтобы рисовать произвольную траекторию в реальном времени, не нажимая каждый раз кнопку мыши, буду рад и такому варианту Улыбающийся
Записан
alexman
Гость
« Ответ #3 : Март 24, 2010, 10:09 »

А если рассмотреть линию, которую ресуешь, как item?
Во втором абзаце я написал, что при таком раскладе сильно падает производительность. + Рисую не обязательно линию, может быть любая траектория.
 Хотя если предложишь, как это реализовать, например через path, чтобы рисовать произвольную траекторию в реальном времени, не нажимая каждый раз кнопку мыши, буду рад и такому варианту Улыбающийся
Сорри! Не дочитал до конца...
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #4 : Март 24, 2010, 11:34 »

Перегружая QGraphicsView::paintEvent() без вызова оригинального paintEvent() вы просто не дали возможность отрисовывть QGraphicsItems.
Для ваших целей лучше подойдёт следующее:
Код
C++ (Qt)
void YourGraphicsView::drawForeground( QPainter* painter, const QRectF& rect )
{
   QGraphicsView::drawForeground( painter, rect );
 
   if( yourDrawRect.intersects( rect ) )   // your mouse painting
     ...
}
 
Но не мешало бы более конкретизировать задачу ...
« Последнее редактирование: Март 24, 2010, 11:35 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
elive
Гость
« Ответ #5 : Март 24, 2010, 13:01 »

Перегружая QGraphicsView::paintEvent() без вызова оригинального paintEvent() вы просто не дали возможность отрисовывть QGraphicsItems.
Для ваших целей лучше подойдёт следующее:
Код
C++ (Qt)
void YourGraphicsView::drawForeground( QPainter* painter, const QRectF& rect )
{
   QGraphicsView::drawForeground( painter, rect );
 
   if( yourDrawRect.intersects( rect ) )   // your mouse painting
     ...
}
 
Но не мешало бы более конкретизировать задачу ...

Спасибо, помогло. Теперь думаю как при нажатии на айтем передавать рисование в QGraphicsView...
Записан
ufna
Гость
« Ответ #6 : Март 24, 2010, 13:05 »

для вью задай setAcceptChildEvents(true)
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Март 24, 2010, 13:11 »

Цитировать
для вью задай setAcceptChildEvents(true)
Это в какой версии Qt такое есть?

Цитировать
Теперь думаю как при нажатии на айтем передавать рисование в QGraphicsView...
item->update()
Записан

Qt 5.11/4.8.7 (X11/Win)
elive
Гость
« Ответ #8 : Март 24, 2010, 13:44 »

item->update()

 Мне надо, чтобы кликая по области сцены, рисование не происходило. А при нажатии на айтем (mousePress), рисование проходило уже во View. Если в айтеме прописать mousePressEvent, а во View - mouseMoveEvent, то рисование идёт в любом случае, просто линия получается непрерывная. Думаю надо как-то по-заковырестее организовывать, может быть ловить все события и сигналами слать во View (drawForeground)? В физическом смысле, мне нужно при нажатии на объект рисовать его траекторию, по которой он впоследствии будет двигаться.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #9 : Март 24, 2010, 14:16 »

Судя по всему вы выставили у элементов флаг QGraphicsItem::ItemIsSelectable.
Предлагаю его не выставлять, а в YourGraphicsView::mousePressEvent() находить нужный элемент и вызывать его update().
Записан

Qt 5.11/4.8.7 (X11/Win)
elive
Гость
« Ответ #10 : Март 24, 2010, 15:15 »

Судя по всему вы выставили у элементов флаг QGraphicsItem::ItemIsSelectable.
Предлагаю его не выставлять, а в YourGraphicsView::mousePressEvent() находить нужный элемент и вызывать его update().

Не очень понимаю, зачем вызывать update для item'a.
Как я понял, вы предлагаете сравнивать позицию мыши и перебирать позиции всех айтемов, и если они совпадают производить рисование? Попробую так.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #11 : Март 24, 2010, 16:44 »

Цитировать
Не очень понимаю, зачем вызывать update для item'a.
Единственный нормальный способ сказать QGraphicsView-у нарисовать конкретный елемент - это вызвать update() этого элемента.

Цитировать
Как я понял, вы предлагаете сравнивать позицию мыши и перебирать позиции всех айтемов, и если они совпадают производить рисование?
Перебирать необязательно
Код
C++ (Qt)
void YourGraphicsView::mousePressEvent( QMouseEvent* e )
{
     QPoint p( mapToScene( e->pos() ).toPoint() );
     QGraphicsItem* item = itemAt( p );
     if( item )
       item->update();
}
 

PS. Если елементы пересекаются, используйте items().

Хм, я похоже немного не так вас понял.
Ваш случай с YourGraphicsItem::mousePressEvent() по идее должен был делать тоже самое.
Похоже вы просто не так делаете отрисовку в drawForeground().
« Последнее редактирование: Март 24, 2010, 16:54 от GreatSnake » Записан

Qt 5.11/4.8.7 (X11/Win)
elive
Гость
« Ответ #12 : Март 25, 2010, 08:58 »

Хм, я похоже немного не так вас понял.
Ваш случай с YourGraphicsItem::mousePressEvent() по идее должен был делать тоже самое.
Похоже вы просто не так делаете отрисовку в drawForeground().

Всмысле тоже самое? В drawForeground я только создаю подложку (QImage), рисую по событию mousePressEvent во View, т.к. рисовать в Item более затратно.
Вместо update, как понимаю, буду просто вызывать QPainter и рисовать.
« Последнее редактирование: Март 25, 2010, 09:02 от elive » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #13 : Март 25, 2010, 11:10 »

Цитировать
В drawForeground я только создаю подложку (QImage)
QGraphicsView отрисовывет сцену в 3 этапа - сначала отрисовывает подложку вызывая drawBackground(), потом отрисовывает сами элементы вызывая paint() этих элементов и уже после этого вызывает drawForeground(), чтобы отрисовать всё что вы пожелаете поверх нарисованной сцены. Так что вы делаете что-то не так и не хотите более подробно объяснить, что реально вы хотите получить на выходе.
Записан

Qt 5.11/4.8.7 (X11/Win)
fuCtor
Гость
« Ответ #14 : Март 25, 2010, 11:22 »

Так же узнать item на который кликнули можно используя:
Код
C++ (Qt)
QGraphicsView::mouseMoveEvent(event);
QGraphicsItem * item = scene()->mouseGrabberItem();

Только в этом случае item-ы должны принимать события мыши, иначе будет 0.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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