На этом шаге рассмотрим иерархию классов событий графического представления.
События модели могут передаваться отдельным элементам, находящимся в модели. Класс QGraphicsView является наследником класса QAbstractScrollArea, поэтому можно переопределить и воспользоваться любым из методов обработки событий этого класса, но это не совсем удобный подход. Предположим, что пользователь нажал мышью на один из элементов сцены. Для того чтобы выяснить, что это за элемент, нужно получить указатель на объект сцены вызовом метода QGraphicsView::scene(), затем определить, какие элементы сцены находятся на координатах указателя мыши, и выбрать из них самый верхний. И если элемент должен как-то отреагировать на это событие, то нужно будет вызвать соответствующий метод.
Самая интересная возможность при обработке событий — это их обработка из самих элементов. Внутренне это работает следующим образом: представление получает события мыши и клавиатуры, затем оно переводит их в события для сцены, изменяя координаты в соответствии с координатами сцены, и передает событие нужному элементу. Если элемент получает событие мыши, то сцена сама позаботится, чтобы координаты были приведены к локальным координатам элемента.
На рис. 1 показана иерархия событий, которые способен получать элемент.
Рис.1. Иерархия классов событий графического представления
Элементы могут обрабатывать события клавиатуры, мыши, а также события, возникающие при попадании указателя мыши в их область (QGraphicsHoverEvent) и при вызове контекстного меню (QGraphicsContextMenuEvent).
Существует возможность создания и обработки событий перетаскивания (drag & drop). Элементы могут как разрешать, так и запрещать поддержку перетаскивания, вызывая метод setAcceptDrops(). Для управления принятием сбрасываемых объектов необходимо переопределить методы dragEnterEvent(), dragMoveEvent(), dragLeaveEvent() и dropEvent().
Для того чтобы начать перетаскивание из элемента, надо создать объект класса QDrag, передав ему виджет представления, из которого происходит перетаскивание. Элементы могут отображаться в нескольких представлениях, но перетаскивание происходит только из какого-то одного. Для того чтобы получить указатель виджета этого представления, нужно вызвать метод QGraphicsSceneEvent::widget(). Для реализации перетаскивания из элементов надо переопределить методы обработки событий мыши.
На следующем шаге рассмотрим пример обработки событий.