Skip to content
Snippets Groups Projects
graphics_graph_event.py 9.14 KiB
Newer Older
  • Learn to ignore specific revisions
  • Andreas Bolin's avatar
    Andreas Bolin committed
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    """B-ASIC Scheduler-gui Graphics Graph Event Module.
    
    Contains event filters and handlers for GraphicsGraphItem objects."""
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    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 (
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        Qt, QObject, QRect, QRectF, QPoint, QSize, QSizeF, QByteArray, Slot, QEvent)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    from qtpy.QtGui     import (
        QPaintEvent, QPainter, QPainterPath, QColor, QBrush, QPen, QFont, QPolygon, QIcon, QPixmap,
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        QLinearGradient, QTransform, QCursor, QFocusEvent)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    from qtpy.QtWidgets import (
        QGraphicsView, QGraphicsScene, QGraphicsWidget,
        QGraphicsLayout, QGraphicsLinearLayout, QGraphicsGridLayout, QGraphicsLayoutItem, QGraphicsAnchorLayout,
        QGraphicsItem, QGraphicsItemGroup, QGraphicsPathItem, QGraphicsLineItem, QGraphicsRectItem,
        QStyleOptionGraphicsItem, QWidget,
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        QGraphicsObject, QGraphicsSceneMouseEvent, QGraphicsSceneHoverEvent, QGraphicsSceneContextMenuEvent,
        QGraphicsSceneDragDropEvent, QGraphicsSceneWheelEvent)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    from qtpy.QtCore    import (
        QPoint, QPointF)
    
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    from abc import ABC
    from graphics_component_item import GraphicsComponentItem
    
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    # class GraphicsGraphEvent(ABC):
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    class GraphicsGraphEvent(QGraphicsItem):
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        """Event filter and handlers for GraphicsGraphItem"""
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        # _components:   list[GraphicsComponentItem]
        _current_pos: QPointF
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        # def __init__(self, parent: QGraphicsItem = None):
        #     super().__init__(parent)
            # self._current_pos: QPointF()
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            # self.setAcceptedMouseButtons(Qt.LeftButton)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            # self.setFlag(QGraphicsItem.ItemIsMovable)
            # self.setFlag(QGraphicsItem.ItemIsSelectable)
            # self.setAcceptHoverEvents(True)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            # self.setFlag(QGraphicsItem.ItemSendsGeometryChanges)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            
            # self.setFlag(QGraphicsItem.ItemIsMovable)
            # self.setFlag(QGraphicsItem.ItemIsSelectable)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            # self.setAcceptHoverEvents(True)
            # print(f'GraphicsGraphItem.handlesChildEvents(): {self.handlesChildEvents()}')
            # self.setHandlesChildEvents(True)   # PySide2 QGraphicsItemGroup default: true. PyQt5 not an option
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            # self.setAcceptedMouseButtons(Qt.NoButton)
    
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        #################
        #### 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."""
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            for item in self._components:
    
    Andreas Bolin's avatar
    Andreas Bolin committed
                item.installSceneEventFilter(self)
            self.setFiltersChildEvents(True)    # default false
            
        def removeSceneEventFilters(self) -> None:
            """Removes an event filter on 'item' from 'self'."""
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            for item in self._components:
    
    Andreas Bolin's avatar
    Andreas Bolin committed
                item.removeSceneEventFilter(self)
            self.setFiltersChildEvents(False)
            
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        # def sceneEventFilter(self, item: QGraphicsItem, event: QEvent) -> bool:
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        def sceneEventFilter(self, item: QGraphicsItem, event: QEvent) -> bool:
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            """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_}')
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            # if event.button():
            #     # print(f'Graph -->\t{type_}\t{item}')
            #     print(f'-------->\t{event.button()}')
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            # scene = self.scene()
            # mouse_grabber = scene.mouseGrabberItem()
            # print(f'mouseGrabberItem() before: {mouse_grabber}')
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            if isinstance(item, GraphicsComponentItem):
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            
                switch = {
    
    Andreas Bolin's avatar
    Andreas Bolin committed
                    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
    
    Andreas Bolin's avatar
    Andreas Bolin committed
                }
    
    Andreas Bolin's avatar
    Andreas Bolin committed
    
    
    Andreas Bolin's avatar
    Andreas Bolin committed
                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)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            # else: 
            #     print(f'Graph -->\t{type(item).__name__}\t{type_}')
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            
            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
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        ###############################################
        #### Event Handlers: GraphicsComponentItem ####
        ###############################################
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        def comp_focusInEvent(self, item: QGraphicsItem, event: QFocusEvent) -> bool: 
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            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:
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            """Set the position of the graphical element in the graphic scene, 
            translate coordinates of the cursor within the graphic element 
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            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)
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            return True
        
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        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()
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            return True
        
        def comp_mouseReleaseEvent(self, item: QGraphicsItem, event: QGraphicsSceneMouseEvent) -> bool:
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            """Changes the cursor to OpenHandCursor when releasing an object."""
            item.setCursor(QCursor(Qt.OpenHandCursor))
            event.accept()
    
    Andreas Bolin's avatar
    Andreas Bolin committed
            return True
             
    
    
    Andreas Bolin's avatar
    Andreas Bolin committed
        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 ####
        ###############################################