Russian Qt Forum
Июня 09, 2025, 02:01 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Групповые операции на QGraphicsScene  (Прочитано 6425 раз)
SubaroMows
Гость
« : Апреля 18, 2012, 21:17 »

Доброе время суток. Возникла проблема с групповыми операциями над объектами на QGraphicsScene. Цель - RubberBandDrag объектов, после чего выделенные объекты можно таскать по сцене как группу. На сцене есть 2 типа объектов - вершины и дуги. Вершины - QGraphicsTextItem, а дуги привязаны к парам вершин и отрисовываются в paint у QGraphicsItem. В коде отрисовки дуг берутся координаты вершин, которые дуга связывает и  рисуется линия. Перерисовка дуг происходит при вызове itemChange с ItemPositionHasChanged вершиной. При добавлении вершин в QGraphicsItemGroup и движении всей группы itemChange перестаёт вызываться, стрелки перестают перерисовываться. В принципе поведение ожидаемо, все объекты, помещённые в группу размещаются в другой системе координат, в которой они стоят неподвижно.
Какие есть варианты решения проблемы, желательно малой кровью?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Апреля 18, 2012, 21:20 »

( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ) на группу выставлены?
Записан

Qt 5.11/4.8.7 (X11/Win)
iroln
Гость
« Ответ #2 : Апреля 19, 2012, 14:34 »

SubaroMows, при выделении "резиновой лентой" элементы автоматом должны группироваться же, или ты их сам добавляешь в группу?

У меня есть подобная программа, только там граф - вершины+рёбра. При таскании группы вершин рёбра нормально перерисовываются. Программу писал давно, но сейчас вижу в своём коде такое:
Код
C++ (Qt)
//------------------------------------------------------------------------------
Node::Node()
{
   nodeTextColor = Qt::blue;
   nodeForegroundColor = Qt::darkCyan;
   nodeBackgroundColor = QColor(254, 247, 175);
 
   //NOTE: Для генерации события ItemPositionHasChanged нужен флаг ItemSendsGeometryChanges!
   setFlags(ItemIsMovable | ItemIsSelectable | ItemSendsGeometryChanges);
}
 
//------------------------------------------------------------------------------
QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
{
   if (change == ItemPositionHasChanged) {
       foreach (Edge *edge, nodeEdges)
           edge->trackNodes();
   }
 
   return QGraphicsItem::itemChange(change, value);
}
 
« Последнее редактирование: Апреля 19, 2012, 17:11 от iroln » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Апреля 19, 2012, 15:55 »

[offtop]Такой вопросик

Ну да, в изометрии хорошо двигать. А если view в перспективе? (ну конечно параметры перспективы заданы). Потянет ли QGraphicsScene - или "придется изыскивать" др либы?

Спвсибо

Записан
SubaroMows
Гость
« Ответ #4 : Апреля 19, 2012, 18:52 »

( QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable ) на группу выставлены?
выставлены, проблема в том, при движении группы каждый элемент, находящийся в группе не получает события о перемещении по сцене, ввиду этого не перерисовываются стрелки
Записан
SubaroMows
Гость
« Ответ #5 : Апреля 19, 2012, 18:53 »

У меня есть подобная программа, только там граф - вершины+рёбра. При таскании группы вершин рёбра нормально перерисовываются. Программу писал давно, но сейчас вижу в своём коде такое:
у меня аналогичный код, проблема этого кода описал чуть выше
Записан
SubaroMows
Гость
« Ответ #6 : Апреля 19, 2012, 18:55 »

SubaroMows, при выделении "резиновой лентой" элементы автоматом должны группироваться же, или ты их сам добавляешь в группу?

а во что они должны группироваться? Как работать с полученной после выделения группой?
Записан
iroln
Гость
« Ответ #7 : Апреля 19, 2012, 19:01 »

SubaroMows, я не писал никакого дополнительного кода для таскания одновременно нескольких элементов. Они сами таскаются все вместе после выделения их "резиновой лентой". Если тебе надо только это действие для группы элементов, и оно автоматом не заработало, видимо что-то ты там перемудрил.
Записан
SubaroMows
Гость
« Ответ #8 : Апреля 19, 2012, 19:27 »

iroln, после резиновой ленты элементы выделены, но таскаются по одному.
мой код, обрабатывающий события мышки при этом полностью убран
резиновая лента лишь заполняет список выбранных объектов
при этом не создаются никакие объекты

PS: можешь выложить свой проект? посмотреть как у тебя тоскаются
« Последнее редактирование: Апреля 19, 2012, 19:43 от SubaroMows » Записан
iroln
Гость
« Ответ #9 : Апреля 19, 2012, 21:07 »

SubaroMows, Элементы перестают таскаться группой при выделении только если переопределить обработчики Mouse Event в классе элемента и не вызывать стандартные обработчики. В моей программе эти обработчики для узлов не переопределены, поэтому элементы таскаются группой. Такое поведение по-умолчанию работает. Можешь сам проверить, создать минимальный проект сцену + вид + два любых айтема. Они будут таскаться вместе при выделении обоих. Чтобы у тебя всё таскалось как надо, вызывай стандартные обработчики событий мыши внутри своих переопределённых методов.

Пример:
Код
C++ (Qt)
QGraphicsItem::mousePressEvent(event);

Цитировать
мой код, обрабатывающий события мышки при этом полностью убран
Но методы (mousePressEvent/mouseReleaseEvent/mouseMoveEvent) переопределены для элемента, так ведь?
« Последнее редактирование: Апреля 19, 2012, 21:10 от iroln » Записан
SubaroMows
Гость
« Ответ #10 : Апреля 22, 2012, 08:55 »

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


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