Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Иволга от Июль 06, 2016, 10:02



Название: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: Иволга от Июль 06, 2016, 10:02
Добрый день.

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


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: Hellraiser от Июль 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();
 }
}


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: Иволга от Июль 06, 2016, 10:33
Спасибо, сейчас попробую.)


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: Иволга от Июль 06, 2016, 11:51
Не получилось. Происходит что-то непонятное. Внутри объекта сцены "qDebug() << type()" всегда выводит 2, однако в обработчике для сцены "qDebug() << item->type()" всегда выводит 6 - независимо, по объекту я щёлкаю или по пустой сцене. Как будто бы сцена поверх объектов закрыта чем-то ещё, полностью прозрачным и с типом 6. Установка для объектов zValue = 1000 не помогает.


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: Hellraiser от Июль 06, 2016, 12:20
type со значением 6, согласно исходникам, соответствует QGraphicsLineItem.


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: GreatSnake от Июль 06, 2016, 12:46
Ищи элемент так
Код
C++ (Qt)
auto l = items( event->pos(), Qt::ContainsItemShape );
QGraphicsItem* item = !l.isEmpty() ? l.first() : nullptr;


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: Racheengel от Июль 06, 2016, 12:53
как-то так:

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


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: Иволга от Июль 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);
  }
}
Это я попробовала в первую очередь. Вторая часть в моём случае не выполняется никогда. То есть сцена в любой позиции видит объект, и этот объект - линия.


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: GreatSnake от Июль 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() ?


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: Racheengel от Июль 06, 2016, 14:15
стоп.
надо event->scenePos();

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


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: Hellraiser от Июль 06, 2016, 14:29
Это мой косяк - код был выдран из похожего обработчика, только для QGraphicsView. Забыл о преобразовании координат.


Название: Re: Обработка события QGraphicsSceneMouseEvent (Qt 4.8)
Отправлено: Иволга от Июль 06, 2016, 14:57
Цитировать
надо event->scenePos();
Точно.
Теперь всё работает как надо. ;D

Всем спасибо! =)