Newer
Older
"""B-ASIC Scheduler-gui Graphics Graph Event Module.
Contains event filters and handlers for GraphicsGraphItem objects."""
import os
import sys
from typing import Any, Optional
from pprint import pprint
from typing import Any, AnyStr, Generic, Protocol, TypeVar, Union, Optional, overload, Final, final
# from typing_extensions import Self, Final, Literal, LiteralString, TypeAlias, final
import numpy as np
from copy import deepcopy
from itertools import combinations
import qtpy
from qtpy import QtCore
from qtpy import QtGui
from qtpy import QtWidgets
# QGraphics and QPainter imports
from qtpy.QtCore import (
Qt, QObject, QRect, QRectF, QPoint, QSize, QSizeF, QByteArray, Slot, QEvent)
from qtpy.QtGui import (
QPaintEvent, QPainter, QPainterPath, QColor, QBrush, QPen, QFont, QPolygon, QIcon, QPixmap,
from qtpy.QtWidgets import (
QGraphicsView, QGraphicsScene, QGraphicsWidget,
QGraphicsLayout, QGraphicsLinearLayout, QGraphicsGridLayout, QGraphicsLayoutItem, QGraphicsAnchorLayout,
QGraphicsItem, QGraphicsItemGroup, QGraphicsPathItem, QGraphicsLineItem, QGraphicsRectItem,
QStyleOptionGraphicsItem, QWidget,
QGraphicsObject, QGraphicsSceneMouseEvent, QGraphicsSceneHoverEvent, QGraphicsSceneContextMenuEvent,
QGraphicsSceneDragDropEvent, QGraphicsSceneWheelEvent)
from abc import ABC
from graphics_component_item import GraphicsComponentItem
# _components: list[GraphicsComponentItem]
_current_pos: QPointF
# def __init__(self, parent: QGraphicsItem = None):
# super().__init__(parent)
# self._current_pos: QPointF()
# self.setFlag(QGraphicsItem.ItemIsMovable)
# self.setFlag(QGraphicsItem.ItemIsSelectable)
# self.setAcceptHoverEvents(True)
# self.setFlag(QGraphicsItem.ItemIsMovable)
# self.setFlag(QGraphicsItem.ItemIsSelectable)
# self.setAcceptHoverEvents(True)
# print(f'GraphicsGraphItem.handlesChildEvents(): {self.handlesChildEvents()}')
# self.setHandlesChildEvents(True) # PySide2 QGraphicsItemGroup default: true. PyQt5 not an option
#################
#### Filters ####
#################
def installSceneEventFilters(self) -> None:
"""Installs an event filter for 'item' on 'self', causing
all events for 'item' to first pass through 'self's
sceneEventFilter() function."""
item.installSceneEventFilter(self)
self.setFiltersChildEvents(True) # default false
def removeSceneEventFilters(self) -> None:
"""Removes an event filter on 'item' from 'self'."""
item.removeSceneEventFilter(self)
self.setFiltersChildEvents(False)
# def sceneEventFilter(self, item: QGraphicsItem, event: QEvent) -> bool:
def sceneEventFilter(self, item: QGraphicsItem, event: QEvent) -> bool:
"""Returns true if the event was filtered (i.e. stopped), otherwise false.
If false is returned, the event is forwarded to the appropriate child in
the event chain."""
# type_ = type(event)
# if type_ != QEvent.GraphicsSceneHoverMove: print(f'Graph -->\t{type(item).__name__}\t{type_}')
# if event.button():
# # print(f'Graph -->\t{type_}\t{item}')
# print(f'-------->\t{event.button()}')
# scene = self.scene()
# mouse_grabber = scene.mouseGrabberItem()
# print(f'mouseGrabberItem() before: {mouse_grabber}')
QEvent.FocusIn: self.comp_focusInEvent,
QEvent.GraphicsSceneContextMenu: self.comp_contextMenuEvent,
QEvent.GraphicsSceneDragEnter: self.comp_dragEnterEvent,
QEvent.GraphicsSceneDragMove: self.comp_dragMoveEvent,
QEvent.GraphicsSceneDragLeave: self.comp_dragLeaveEvent,
QEvent.GraphicsSceneDrop: self.comp_dropEvent,
QEvent.GraphicsSceneHoverEnter: self.comp_hoverEnterEvent,
QEvent.GraphicsSceneHoverMove: self.comp_hoverMoveEvent,
QEvent.GraphicsSceneHoverLeave: self.comp_hoverLeaveEvent,
QEvent.GraphicsSceneMouseMove: self.comp_mouseMoveEvent,
QEvent.GraphicsSceneMousePress: self.comp_mousePressEvent,
QEvent.GraphicsSceneMouseRelease: self.comp_mouseReleaseEvent,
QEvent.GraphicsSceneMouseDoubleClick: self.comp_mouseDoubleClickEvent,
QEvent.GraphicsSceneWheel: self.comp_wheelEvent
handler = switch.get(event.type(), lambda x,y : False)
# ret = handler(item, event)
# print(f'mouseGrabberItem() after: {mouse_grabber}')
# return ret
return handler(item, event)
# else:
# print(f'Graph -->\t{type(item).__name__}\t{type_}')
return False # returns False if event is ignored and pass through event to its child
# def sceneEvent(self, event: QEvent) -> bool:
# print(f'sceneEvent() --> {event.type()}')
# # event.accept()
# # QApplication.sendEvent(self.scene(), event)
# return False
###############################################
#### Event Handlers: GraphicsComponentItem ####
###############################################
def comp_focusInEvent(self, item: QGraphicsItem, event: QFocusEvent) -> bool:
return False
def comp_contextMenuEvent(self, item: QGraphicsItem, event: QGraphicsSceneContextMenuEvent) -> bool:
return False
def comp_dragEnterEvent(self, item: QGraphicsItem, event: QGraphicsSceneDragDropEvent) -> bool:
return False
def comp_dragMoveEvent(self, item: QGraphicsItem, event: QGraphicsSceneDragDropEvent) -> bool:
return False
def comp_dragLeaveEvent(self, item: QGraphicsItem, event: QGraphicsSceneDragDropEvent) -> bool:
return False
def comp_dropEvent(self, item: QGraphicsItem, event: QGraphicsSceneDragDropEvent) -> bool:
return False
def comp_hoverEnterEvent(self, item: QGraphicsItem, event: QGraphicsSceneHoverEvent) -> bool:
"""Changes the cursor to OpenHandCursor when hovering an object."""
self.setCursor(QCursor(Qt.OpenHandCursor))
return True
def comp_hoverMoveEvent(self, item: QGraphicsItem, event: QGraphicsSceneHoverEvent) -> bool:
return False
def comp_hoverLeaveEvent(self, item: QGraphicsItem, event: QGraphicsSceneHoverEvent) -> bool:
"""Changes the cursor to ArrowCursor when leaving an object."""
self.setCursor(QCursor(Qt.ArrowCursor))
return True
def comp_mouseMoveEvent(self, item_: QGraphicsItem, event: QGraphicsSceneMouseEvent) -> bool:
"""Set the position of the graphical element in the graphic scene,
translate coordinates of the cursor within the graphic element
in the coordinate system of the parent object."""
# Qt.DragMoveCursor
# button = event.button()
item = self.scene().mouseGrabberItem()
dx = (item.mapToParent(event.pos()) - self._current_pos).x()
if dx > 5.05:
pos = item.x() + 10.0
if self.is_valid_pos(pos):
item.setX(pos)
self._current_pos.setX(self._current_pos.x() + 10.0)
elif dx < -5.05:
pos = item.x() - 10.0
if self.is_valid_pos(pos):
item.setX(pos)
self._current_pos.setX(self._current_pos.x() - 10.0)
def comp_mousePressEvent(self, item_: QGraphicsItem, event: QGraphicsSceneMouseEvent) -> bool:
"""Changes the cursor to ClosedHandCursor when grabbing an object."""
item = self.scene().mouseGrabberItem()
self._current_pos = item.mapToParent(event.pos())
item.setCursor(QCursor(Qt.ClosedHandCursor))
event.accept()
return True
def comp_mouseReleaseEvent(self, item: QGraphicsItem, event: QGraphicsSceneMouseEvent) -> bool:
"""Changes the cursor to OpenHandCursor when releasing an object."""
item.setCursor(QCursor(Qt.OpenHandCursor))
event.accept()
def comp_mouseDoubleClickEvent(self, item: QGraphicsItem, event: QGraphicsSceneMouseEvent) -> bool:
return False
def comp_wheelEvent(self, item: QGraphicsItem, event: QGraphicsSceneWheelEvent) -> bool:
return False
###############################################
#### Event Handlers: GraphicsComponentItem ####
###############################################