graphics_node_item.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. """
  2. QGraphics representation class for a node element.
  3. An object with a defined size (120x120) on screen which can either be
  4. an image file or a set of primitives.
  5. """
  6. from enum import Enum
  7. from PyQt5.QtWidgets import QGraphicsItem, QStyleOptionGraphicsItem, QWidget
  8. from PyQt5.Qt import QRectF, QPainter, QFont, Qt, QBrush, QColor
  9. class IconType(Enum):
  10. IMAGE = 0
  11. PRIMITIVE = 1
  12. class GraphicsNodeItem(QGraphicsItem):
  13. def __init__(self, node_id, node_type="", consyn=None):
  14. QGraphicsItem.__init__(self)
  15. self.node_id = node_id
  16. self._type = node_type
  17. self._consyn = consyn
  18. self._icon_type = None
  19. self._font = QFont()
  20. self._font.setPixelSize(12)
  21. self.setZValue(1.0)
  22. def set_type(self, node_type):
  23. self._type = node_type
  24. self.update(self.boundingRect())
  25. def update_consyn(self, consyn):
  26. self._consyn = consyn
  27. self.update(self.boundingRect())
  28. def get_type(self):
  29. return self._type
  30. def boundingRect(self):
  31. bbox = QRectF(0, 0, 120, 120)
  32. return bbox
  33. def paint(self, painter, option, widget=None):
  34. # type: (QPainter, QStyleOptionGraphicsItem, QWidget) -> None
  35. # draw type text and bounding rectangle
  36. painter.setFont(self._font)
  37. painter.setBrush(QBrush(Qt.white))
  38. painter.drawRect(self.boundingRect())
  39. text_box = QRectF(0, 100, 120, 20)
  40. painter.drawRect(text_box)
  41. painter.setBrush(QBrush(QColor(0, 0, 0, 0)))
  42. painter.drawText(text_box, Qt.AlignCenter | Qt.TextDontClip, self._type)
  43. # draw concrete syntax
  44. if not self._consyn:
  45. # nothing to draw, so leave empty
  46. return
  47. # first, determine if we have an actual image file or a primitive group
  48. for item in self._consyn:
  49. if item["type"] == "Icon":
  50. if item["is_primitive"]:
  51. self._icon_type = IconType.PRIMITIVE
  52. else:
  53. self._icon_type = IconType.IMAGE
  54. break
  55. if not self._icon_type:
  56. print("Could not determine CS icon type for type {}".format(self._type))
  57. return
  58. if self._icon_type == IconType.IMAGE:
  59. # an actual image file, so load and display it
  60. img_data = None
  61. for item in self._consyn:
  62. if item["type"] == "Image":
  63. img_data = item["data"]
  64. break
  65. if not img_data:
  66. print("Could not find image data for type {}".format(self._type))
  67. return
  68. # TODO: paint image in area by converting it to QImage and draw
  69. else:
  70. # a set of primitives
  71. for item in self._consyn:
  72. item_type = item["type"]
  73. # ignore the "useless"
  74. if item_type in ["Icon", "PrimitiveGroup", "PrimitiveGroupPrimitive"]:
  75. continue
  76. if item_type == "Rectangle":
  77. rect = QRectF(item["x"], item["y"], item["width"], item["height"])
  78. painter.drawRect(rect)
  79. elif item_type == "Ellipse":
  80. painter.drawEllipse(item["x"], item["y"], item["width"], item["height"])
  81. elif item_type == "Line":
  82. painter.drawLine(item["start_x"], item["start_y"], item["end_x"], item["end_y"])
  83. else:
  84. print("No paint implemented for primitive {}".format(item_type))