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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)  (Прочитано 6798 раз)
Иволга
Чайник
*
Offline Offline

Сообщений: 58



Просмотр профиля
« : Июль 06, 2016, 10:02 »

Добрый день.

У меня есть сцена (потомок QGraphicsScene) и куча объектов на ней (потомки QGraphicsPathItem). Для обоих классов переопределён обработчик мыши mousePressEvent(QGraphicsSceneMouseEvent*).
Мне нужно, чтобы обработчик для сцены вызывался только тогда, когда мышь щёлкает по пустому месту на сцене (где нет объектов). Если же мышь щёлкает по объекту, нужен обработчик для объектов. Однако, этого не происходит - всегда вызывается обработчик для сцены. Обработчик для объектов вызывается (и правильно работает), только если обработчик для сцены убрать совсем (из кода). Как решить эту проблему? Нужны оба обработчика.
Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #1 : Июль 06, 2016, 10:31 »

Примерно так:
Код
C++ (Qt)
void MyScene::mousePressEvent (QGraphicsSceneMouseEvent * event)
{
 QGraphicsItem *item = itemAt(event->pos());
 if (item && item->type() == ...) {
    QGraphicsScene::mousePressEvent(event);
 }
 else {
    ...
    event->accept();
 }
}
« Последнее редактирование: Июль 06, 2016, 10:33 от Hellraiser » Записан
Иволга
Чайник
*
Offline Offline

Сообщений: 58



Просмотр профиля
« Ответ #2 : Июль 06, 2016, 10:33 »

Спасибо, сейчас попробую.)
Записан
Иволга
Чайник
*
Offline Offline

Сообщений: 58



Просмотр профиля
« Ответ #3 : Июль 06, 2016, 11:51 »

Не получилось. Происходит что-то непонятное. Внутри объекта сцены "qDebug() << type()" всегда выводит 2, однако в обработчике для сцены "qDebug() << item->type()" всегда выводит 6 - независимо, по объекту я щёлкаю или по пустой сцене. Как будто бы сцена поверх объектов закрыта чем-то ещё, полностью прозрачным и с типом 6. Установка для объектов zValue = 1000 не помогает.
Записан
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #4 : Июль 06, 2016, 12:20 »

type со значением 6, согласно исходникам, соответствует QGraphicsLineItem.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #5 : Июль 06, 2016, 12:46 »

Ищи элемент так
Код
C++ (Qt)
auto l = items( event->pos(), Qt::ContainsItemShape );
QGraphicsItem* item = !l.isEmpty() ? l.first() : nullptr;
Записан

Qt 5.11/4.8.7 (X11/Win)
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #6 : Июль 06, 2016, 12:53 »

как-то так:

Код:
void MyScene::mousePressEvent (QGraphicsSceneMouseEvent * event)
{
  QGraphicsItem *item = itemAt(event->pos());
  if (item) {
     ...
     event->accept();
  }
  else {
     QGraphicsScene::mousePressEvent(event);
  }
}
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Иволга
Чайник
*
Offline Offline

Сообщений: 58



Просмотр профиля
« Ответ #7 : Июль 06, 2016, 13:31 »

Цитировать
type со значением 6, согласно исходникам, соответствует QGraphicsLineItem
Да, они там есть - образуют сетку с шагом 80 пикселов. Я щёлкаю между линиями, а объекты отрисовываются поверх этих линий. Почему сцена считает, что на ней только линии - непонятно. Если же линии убрать, сцена вообще не видит никаких объектов на себе. Хотя на ней есть текстовые метки и мои объекты.
Цитировать
Код:
auto l = items( event->pos(), Qt::ContainsItemShape );
QGraphicsItem* item = !l.isEmpty() ? l.first() : nullptr;
Код пришлось подправить (мой компилятор не всё понял здесь), но результат получился аналогичный (сцена видит только линии).
Мой код:
Код:
	QList<QGraphicsItem*> l = items(event->pos(), Qt::ContainsItemShape, Qt::DescendingOrder );
QGraphicsItem* item = !l.isEmpty() ? l.first() : NULL;

Цитировать
Код:
 QGraphicsItem *item = itemAt(event->pos());
  if (item) {
     ...
     event->accept();
  }
  else {
     QGraphicsScene::mousePressEvent(event);
  }
}
Это я попробовала в первую очередь. Вторая часть в моём случае не выполняется никогда. То есть сцена в любой позиции видит объект, и этот объект - линия.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #8 : Июль 06, 2016, 13:44 »

Код пришлось подправить (мой компилятор не всё понял здесь), но результат получился аналогичный (сцена видит только линии).
Ну дык исключи линии из поиска
Код
C++ (Qt)
QGraphicsItem* item = 0;
for( int i = 0; i < l.count(); i++ )
   if( l.at( i )->type() != QGraphicsLineItem::Type )
   {
        item = l.at( i );
        break;
   }

Цитировать
Да, они там есть - образуют сетку с шагом 80 пикселов.
А зачем делать сетку из элементов?
Почему её не нарисовать в перегруженном QGraphicsScene::drawForeground() ?
Записан

Qt 5.11/4.8.7 (X11/Win)
Racheengel
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2679


Я работал с дискетам 5.25 :(


Просмотр профиля
« Ответ #9 : Июль 06, 2016, 14:15 »

стоп.
надо event->scenePos();

иначе оно берет экранные координаты, а сцена работает только с логическими.
Записан

What is the 11 in the C++11? It’s the number of feet they glued to C++ trying to obtain a better octopus.

COVID не волк, в лес не уйдёт
Hellraiser
Бывалый
*****
Offline Offline

Сообщений: 451


Просмотр профиля
« Ответ #10 : Июль 06, 2016, 14:29 »

Это мой косяк - код был выдран из похожего обработчика, только для QGraphicsView. Забыл о преобразовании координат.
Записан
Иволга
Чайник
*
Offline Offline

Сообщений: 58



Просмотр профиля
« Ответ #11 : Июль 06, 2016, 14:57 »

Цитировать
надо event->scenePos();
Точно.
Теперь всё работает как надо. Смеющийся

Всем спасибо! =)
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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