graphics_node_item.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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
  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. def set_type(self, node_type):
  22. self._type = node_type
  23. self.update(self.boundingRect())
  24. def update_consyn(self, consyn):
  25. self._consyn = consyn
  26. self.update(self.boundingRect())
  27. def get_type(self):
  28. return self._type
  29. def boundingRect(self):
  30. bbox = QRectF(0, 0, 120, 120)
  31. return bbox
  32. def paint(self, painter, option, widget=None):
  33. # type: (QPainter, QStyleOptionGraphicsItem, QWidget) -> None
  34. # draw type text and bounding rectangle
  35. painter.setFont(self._font)
  36. painter.drawRect(self.boundingRect())
  37. text_box = QRectF(0, 100, 120, 20)
  38. painter.drawRect(text_box)
  39. painter.drawText(text_box, Qt.AlignCenter | Qt.TextDontClip, self._type)
  40. # draw concrete syntax
  41. if not self._consyn:
  42. # nothing to draw, so leave empty
  43. return
  44. # first, determine if we have an actual image file or a primitive group
  45. for item in self._consyn:
  46. if item["type"] == "Icon":
  47. if item["is_primitive"]:
  48. self._icon_type = IconType.PRIMITIVE
  49. else:
  50. self._icon_type = IconType.IMAGE
  51. break
  52. if not self._icon_type:
  53. print("Could not determine CS icon type for type {}".format(self._type))
  54. return
  55. if self._icon_type == IconType.IMAGE:
  56. # an actual image file, so load and display it
  57. img_data = None
  58. for item in self._consyn:
  59. if item["type"] == "Image":
  60. img_data = item["data"]
  61. break
  62. if not img_data:
  63. print("Could not find image data for type {}".format(self._type))
  64. return
  65. # TODO: paint image in area by converting it to QImage and draw
  66. else:
  67. # a set of primitives
  68. for item in self._consyn:
  69. item_type = item["type"]
  70. # ignore the "useless"
  71. if item_type in ["Icon", "PrimitiveGroup", "PrimitiveGroupPrimitive"]:
  72. continue
  73. if item_type == "Rectangle":
  74. rect = QRectF(item["x"], item["y"], item["width"], item["height"])
  75. painter.drawRect(rect)
  76. elif item_type == "Ellipse":
  77. painter.drawEllipse(item["x"], item["y"], item["width"], item["height"])
  78. elif item_type == "Line":
  79. painter.drawLine(item["start_x"], item["start_y"], item["end_x"], item["end_y"])
  80. else:
  81. print("No paint implemented for primitive {}".format(item_type))