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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: [РЕШЕНО] Отслеживание передвижений на сцене.  (Прочитано 3952 раз)
kamil
Гость
« : Март 01, 2016, 12:22 »

Такая ситуация:
Есть два класса унаследованных от QGraphicsView и QGraphicsItem.

У QGraphicsView переопределен mouseMoveEvent(QMouseEvent* event), для скролла сцены.
Также есть множество QGraphicsItem, некоторые из них можно перемещать (setFlag(QGraphicsItem::ItemIsMovable)).

Проблема в том, что на самом деле из перемещать нельзя, так как mouseMoveEvent у QGraphicsView вызывается как раз когда ты пытаешься перетащить элемент, и перетаскивается вся сцена вместо QGraphicsItem.

Решение, в общем-то ясно - нужно в mouseMoveEvent отслеживать, не началось ли перетаскивание элемента на сцене, и если началось, не двигать сцену. Но как узнать у сцены, что в данный момент активно перетаскивание?

В общем, как-то так:
Цитировать
void MyView::mouseMoveEvent(QMouseEvent* event) {
    static QPoint previousPoint = event->pos();
    if( event->buttons() & Qt::LeftButton /*&& !scene()->isItemsMoves()Непонимающий */ ) {
        addOffset( event->pos() - previousPoint );
        updateTransform( scale(), offset() );
    }
    previousPoint = event->pos();
    QGraphicsView::mouseMoveEvent(event);
}

Пока я сделал так, что есть какая-то глобальная переменная, и каждый раз когда происходит клик перемещаемом QGraphicsItem эта переменная ставится в 1, когда отпускает в 0,  и в mouseMoveEvent происходит проверка этой переменной. Но это не самое лучшее решение. Есть какие идеи?
« Последнее редактирование: Март 11, 2016, 01:22 от kamil » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 582


Просмотр профиля
« Ответ #1 : Март 02, 2016, 08:08 »

Можно сделать, например, так

Код
C++ (Qt)
void MyView::mouseMoveEvent(QMouseEvent* event) {
   QGraphicsView::mouseMoveEvent(event);
   // уже обработано
   if ( event->isAccepted() )
       return;
 
   if( event->buttons() & Qt::LeftButton )
   {
       addOffset( event->pos() - previousPoint );
       updateTransform( scale(), offset() );
   }
   previousPoint = event->pos();
}
 

А в обработчике событий item помечать событие event->accept();
Записан
kamil
Гость
« Ответ #2 : Март 03, 2016, 00:16 »

Можно сделать, например, так

Код
C++ (Qt)
void MyView::mouseMoveEvent(QMouseEvent* event) {
   QGraphicsView::mouseMoveEvent(event);
   // уже обработано
   if ( event->isAccepted() )
       return;
 
   if( event->buttons() & Qt::LeftButton )
   {
       addOffset( event->pos() - previousPoint );
       updateTransform( scale(), offset() );
   }
   previousPoint = event->pos();
}
 

А в обработчике событий item помечать событие event->accept();

Не пошло. Почему-то event всегда event->isAccepted() == false, даже если в mouseMoveEvent у передвигаемых объектов явно вызывать event->accept() перед возвращением. Похоже mouseMoveEvent у QGrahicsScene возвращает not accepted, даже если QGraphicsItem вернул accept.

Может есть еще идеи?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Март 03, 2016, 10:34 »

Пока я сделал так, что есть какая-то глобальная переменная, и каждый раз когда происходит клик перемещаемом QGraphicsItem эта переменная ставится в 1, когда отпускает в 0,  и в mouseMoveEvent происходит проверка этой переменной. Но это не самое лучшее решение. Есть какие идеи?
Не вижу в этом решении ничего плохого. И лучше сделать эти 2 драга явными. Напр юзер нажал и держит пробел - курсор поменялся, ага - это таскать всю сцену. Не нажимал - таскаем айтем(ы)
Записан
kamil
Гость
« Ответ #4 : Март 11, 2016, 01:22 »

Пока я сделал так, что есть какая-то глобальная переменная, и каждый раз когда происходит клик перемещаемом QGraphicsItem эта переменная ставится в 1, когда отпускает в 0,  и в mouseMoveEvent происходит проверка этой переменной. Но это не самое лучшее решение. Есть какие идеи?
Не вижу в этом решении ничего плохого. И лучше сделать эти 2 драга явными. Напр юзер нажал и держит пробел - курсор поменялся, ага - это таскать всю сцену. Не нажимал - таскаем айтем(ы)

Да, похоже решение получше не придумать.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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