butterfly_viewer.aux_comments

Comment items for CustomQGraphicsScene.

Not intended as a script. Used in Butterfly Viewer.

Creates an editable and movable comment on QGraphicsScene at a given scene position.

  1#!/usr/bin/env python3
  2
  3"""Comment items for CustomQGraphicsScene.
  4
  5Not intended as a script. Used in Butterfly Viewer.
  6
  7Creates an editable and movable comment on QGraphicsScene at a given scene position.
  8"""
  9# SPDX-License-Identifier: GPL-3.0-or-later
 10
 11
 12
 13from PyQt5 import QtWidgets, QtCore, QtGui
 14
 15
 16
 17class CommentItem(QtWidgets.QGraphicsRectItem):
 18    """Create an editable and movable comment for QGraphicsScene.
 19
 20    Features:
 21        Editable field for plain text.
 22        Draggable item with visible datum centered at actual location.
 23        Multiple color schemes.
 24
 25    Args:
 26        initial_scene_pos (QPointF): The starting position of the comment datum on the scene.
 27        color (str): The color scheme based on the presets of text color (white, red, blue, black, yellow, green).
 28        comment_text (str): Text of the comment.
 29        set_cursor_on_creation (bool): True to set cursor on comment text field on instantiation; False to ignore.
 30    """
 31    def __init__(self, initial_scene_pos=None, color="white", comment_text="Text", set_cursor_on_creation=False):
 32        super().__init__()
 33
 34        self.comment_text = comment_text
 35        self.pos_on_scene = initial_scene_pos
 36        self.color = color
 37
 38        pen = QtGui.QPen() 
 39        pen.setCosmetic(True)
 40        pen.setWidth(2)
 41        pen.setColor(QtCore.Qt.white) # setColor also works
 42        pen.setCapStyle(QtCore.Qt.SquareCap)
 43        pen.setJoinStyle(QtCore.Qt.MiterJoin)
 44            
 45        brush = QtGui.QBrush()
 46        brush.setColor(QtCore.Qt.white)
 47        brush.setStyle(QtCore.Qt.SolidPattern)
 48
 49        width = 4
 50        height = 4
 51
 52        ellipse_pos_topleft = QtCore.QPointF(-width/2, -height/2)
 53        ellipse_pos_bottomright = QtCore.QPointF(width/2,height/2)
 54
 55        ellipse_rect = QtCore.QRectF(ellipse_pos_topleft, ellipse_pos_bottomright)
 56        self.ellipse_item = QtWidgets.QGraphicsEllipseItem(ellipse_rect)
 57
 58        self.ellipse_item.setPos(0,0)
 59        
 60        self.ellipse_item.setBrush(brush)
 61        self.ellipse_item.setPen(pen)
 62
 63        self.ellipse_item.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresTransformations)
 64
 65        self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(0, 0, 0, 255), xOffset=0, yOffset=0)
 66
 67        dx = 30
 68        dy = -30
 69        point_p1 = QtCore.QPointF(0,0)
 70        point_p2 = QtCore.QPointF(dx,dy)
 71        line = QtCore.QLineF(point_p1, point_p2)
 72        self.line_item = QtWidgets.QGraphicsLineItem(line)
 73        pen = QtGui.QPen() 
 74        pen.setWidth(2)
 75        pen.setColor(QtCore.Qt.white)
 76        pen.setCapStyle(QtCore.Qt.SquareCap)
 77        pen.setJoinStyle(QtCore.Qt.MiterJoin)
 78        self.line_item.setPen(pen)
 79        self.line_item.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresTransformations)
 80        self.line_item.setPos(0,0)
 81        self.line_item.setGraphicsEffect(self.shadow)
 82
 83        self.line_item_bounding_box = QtWidgets.QGraphicsLineItem(line)
 84        # self.line_item_bounding_box = QGraphicsLineItemWithCustomSignals(line)
 85        pen = QtGui.QPen() 
 86        pen.setWidth(20)
 87        pen.setColor(QtCore.Qt.transparent)
 88        pen.setCapStyle(QtCore.Qt.SquareCap)
 89        pen.setJoinStyle(QtCore.Qt.MiterJoin)
 90        self.line_item_bounding_box.setPen(pen)
 91        self.line_item_bounding_box.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable | QtWidgets.QGraphicsItem.ItemIgnoresTransformations)
 92        self.line_item_bounding_box.setPos(self.pos_on_scene.x(), self.pos_on_scene.y())
 93
 94        self.text_item = QtWidgets.QGraphicsTextItem()
 95        self.text_item.setHtml("<div style='background:rgba(0, 0, 0, 31);'>" + "" + "</div>")
 96        self.text_item.setPlainText(self.comment_text)
 97        font = self.text_item.font()
 98        font.setPointSize(12)
 99        self.text_item.setFont(font)
100        self.text_item.setPos(dx+1,dy-14)
101        self.text_item.setDefaultTextColor(QtCore.Qt.white)
102        self.text_item.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresTransformations | QtWidgets.QGraphicsItem.ItemIsFocusable) # QtWidgets.QGraphicsItem.ItemIsSelectable
103        self.text_item.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
104
105        self.text_item.setParentItem(self.line_item)
106        self.ellipse_item.setParentItem(self.line_item)
107        self.line_item.setParentItem(self.line_item_bounding_box)
108
109        self.line_item_bounding_box.setParentItem(self)
110
111        self.set_color(self.color)
112
113        if set_cursor_on_creation:
114            self.set_cursor()
115
116    def set_cursor(self):
117        """Set cursor on the comment text field."""
118        self.text_item.setFocus(QtCore.Qt.MouseFocusReason)
119        self.text_item.setSelected(True);
120        cursor = self.text_item.textCursor()
121        cursor.select(QtGui.QTextCursor.Document)
122        self.text_item.setTextCursor(cursor)
123
124    def get_scene_pos(self):
125        """QPointF: Get datum position of the comment."""
126        scene_pos = self.line_item_bounding_box.pos()
127        return scene_pos
128
129    def get_comment_text_qstring(self):
130        """QString: Get comment text."""
131        text_qstring = self.text_item.toPlainText()
132        return text_qstring
133
134    def get_comment_text_str(self):
135        """str: Get comment text."""
136        text_qstring = self.get_comment_text_qstring()
137        text_str = str(text_qstring)
138        return text_str
139
140    def get_color(self):
141        """str: Get descriptor of color."""
142        color = self.color
143        return color
144
145    def set_color(self, color="white"):
146        """Set color based on the presets of text color (white, red, blue, black, yellow, green).
147
148        Applies highlight behind the text to make it more visible over images.
149
150        Args:
151            color (str): The color scheme based on the presets of text color (white, red, blue, black, yellow, green).
152        """
153        pen_ellipse = self.ellipse_item.pen()
154        pen_line = self.line_item.pen()
155
156        self.color = color
157        needs_background = "dark"
158        color_code = QtCore.Qt.white
159
160        if color == "red":
161            color_code = QtCore.Qt.red
162            needs_background = "light"
163        elif color == "blue":
164            color_code = QtCore.Qt.blue
165            needs_background = "light"
166        elif color == "black":
167            color_code = QtCore.Qt.black
168            needs_background = "light"
169            self.text_item.setHtml("<div style='background:rgba(255, 255, 255, 255);'>" + str(self.text_item.toPlainText()).replace("\n","<br>") + "</div>")
170            self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(255, 255, 255, 255), xOffset=0, yOffset=0)
171            self.line_item.setGraphicsEffect(self.shadow)
172        elif color == "yellow":
173            needs_background = "dark"
174            color_code = QtCore.Qt.yellow
175        elif color == "green":
176            needs_background = "dark"
177            color_code = QtCore.Qt.green
178
179        if needs_background == "light":
180            self.text_item.setHtml("<div style='background:rgba(255, 255, 255, 123);'>" + str(self.text_item.toPlainText()).replace("\n","<br>") + "</div>")
181            self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(255, 255, 255, 255), xOffset=0, yOffset=0)
182        elif needs_background == "dark":
183            self.text_item.setHtml("<div style='background:rgba(0, 0, 0, 31);'>" + str(self.text_item.toPlainText()).replace("\n","<br>") + "</div>")
184            self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(0, 0, 0, 255), xOffset=0, yOffset=0)
185        
186        self.line_item.setGraphicsEffect(self.shadow)
187
188        
189        pen_ellipse.setColor(color_code)
190        pen_line.setColor(color_code)
191
192        self.ellipse_item.setPen(pen_ellipse)
193        self.line_item.setPen(pen_line)
194        self.text_item.setDefaultTextColor(color_code)
class CommentItem(PyQt5.QtWidgets.QGraphicsRectItem):
 18class CommentItem(QtWidgets.QGraphicsRectItem):
 19    """Create an editable and movable comment for QGraphicsScene.
 20
 21    Features:
 22        Editable field for plain text.
 23        Draggable item with visible datum centered at actual location.
 24        Multiple color schemes.
 25
 26    Args:
 27        initial_scene_pos (QPointF): The starting position of the comment datum on the scene.
 28        color (str): The color scheme based on the presets of text color (white, red, blue, black, yellow, green).
 29        comment_text (str): Text of the comment.
 30        set_cursor_on_creation (bool): True to set cursor on comment text field on instantiation; False to ignore.
 31    """
 32    def __init__(self, initial_scene_pos=None, color="white", comment_text="Text", set_cursor_on_creation=False):
 33        super().__init__()
 34
 35        self.comment_text = comment_text
 36        self.pos_on_scene = initial_scene_pos
 37        self.color = color
 38
 39        pen = QtGui.QPen() 
 40        pen.setCosmetic(True)
 41        pen.setWidth(2)
 42        pen.setColor(QtCore.Qt.white) # setColor also works
 43        pen.setCapStyle(QtCore.Qt.SquareCap)
 44        pen.setJoinStyle(QtCore.Qt.MiterJoin)
 45            
 46        brush = QtGui.QBrush()
 47        brush.setColor(QtCore.Qt.white)
 48        brush.setStyle(QtCore.Qt.SolidPattern)
 49
 50        width = 4
 51        height = 4
 52
 53        ellipse_pos_topleft = QtCore.QPointF(-width/2, -height/2)
 54        ellipse_pos_bottomright = QtCore.QPointF(width/2,height/2)
 55
 56        ellipse_rect = QtCore.QRectF(ellipse_pos_topleft, ellipse_pos_bottomright)
 57        self.ellipse_item = QtWidgets.QGraphicsEllipseItem(ellipse_rect)
 58
 59        self.ellipse_item.setPos(0,0)
 60        
 61        self.ellipse_item.setBrush(brush)
 62        self.ellipse_item.setPen(pen)
 63
 64        self.ellipse_item.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresTransformations)
 65
 66        self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(0, 0, 0, 255), xOffset=0, yOffset=0)
 67
 68        dx = 30
 69        dy = -30
 70        point_p1 = QtCore.QPointF(0,0)
 71        point_p2 = QtCore.QPointF(dx,dy)
 72        line = QtCore.QLineF(point_p1, point_p2)
 73        self.line_item = QtWidgets.QGraphicsLineItem(line)
 74        pen = QtGui.QPen() 
 75        pen.setWidth(2)
 76        pen.setColor(QtCore.Qt.white)
 77        pen.setCapStyle(QtCore.Qt.SquareCap)
 78        pen.setJoinStyle(QtCore.Qt.MiterJoin)
 79        self.line_item.setPen(pen)
 80        self.line_item.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresTransformations)
 81        self.line_item.setPos(0,0)
 82        self.line_item.setGraphicsEffect(self.shadow)
 83
 84        self.line_item_bounding_box = QtWidgets.QGraphicsLineItem(line)
 85        # self.line_item_bounding_box = QGraphicsLineItemWithCustomSignals(line)
 86        pen = QtGui.QPen() 
 87        pen.setWidth(20)
 88        pen.setColor(QtCore.Qt.transparent)
 89        pen.setCapStyle(QtCore.Qt.SquareCap)
 90        pen.setJoinStyle(QtCore.Qt.MiterJoin)
 91        self.line_item_bounding_box.setPen(pen)
 92        self.line_item_bounding_box.setFlags(QtWidgets.QGraphicsItem.ItemIsMovable | QtWidgets.QGraphicsItem.ItemIgnoresTransformations)
 93        self.line_item_bounding_box.setPos(self.pos_on_scene.x(), self.pos_on_scene.y())
 94
 95        self.text_item = QtWidgets.QGraphicsTextItem()
 96        self.text_item.setHtml("<div style='background:rgba(0, 0, 0, 31);'>" + "" + "</div>")
 97        self.text_item.setPlainText(self.comment_text)
 98        font = self.text_item.font()
 99        font.setPointSize(12)
100        self.text_item.setFont(font)
101        self.text_item.setPos(dx+1,dy-14)
102        self.text_item.setDefaultTextColor(QtCore.Qt.white)
103        self.text_item.setFlags(QtWidgets.QGraphicsItem.ItemIgnoresTransformations | QtWidgets.QGraphicsItem.ItemIsFocusable) # QtWidgets.QGraphicsItem.ItemIsSelectable
104        self.text_item.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction)
105
106        self.text_item.setParentItem(self.line_item)
107        self.ellipse_item.setParentItem(self.line_item)
108        self.line_item.setParentItem(self.line_item_bounding_box)
109
110        self.line_item_bounding_box.setParentItem(self)
111
112        self.set_color(self.color)
113
114        if set_cursor_on_creation:
115            self.set_cursor()
116
117    def set_cursor(self):
118        """Set cursor on the comment text field."""
119        self.text_item.setFocus(QtCore.Qt.MouseFocusReason)
120        self.text_item.setSelected(True);
121        cursor = self.text_item.textCursor()
122        cursor.select(QtGui.QTextCursor.Document)
123        self.text_item.setTextCursor(cursor)
124
125    def get_scene_pos(self):
126        """QPointF: Get datum position of the comment."""
127        scene_pos = self.line_item_bounding_box.pos()
128        return scene_pos
129
130    def get_comment_text_qstring(self):
131        """QString: Get comment text."""
132        text_qstring = self.text_item.toPlainText()
133        return text_qstring
134
135    def get_comment_text_str(self):
136        """str: Get comment text."""
137        text_qstring = self.get_comment_text_qstring()
138        text_str = str(text_qstring)
139        return text_str
140
141    def get_color(self):
142        """str: Get descriptor of color."""
143        color = self.color
144        return color
145
146    def set_color(self, color="white"):
147        """Set color based on the presets of text color (white, red, blue, black, yellow, green).
148
149        Applies highlight behind the text to make it more visible over images.
150
151        Args:
152            color (str): The color scheme based on the presets of text color (white, red, blue, black, yellow, green).
153        """
154        pen_ellipse = self.ellipse_item.pen()
155        pen_line = self.line_item.pen()
156
157        self.color = color
158        needs_background = "dark"
159        color_code = QtCore.Qt.white
160
161        if color == "red":
162            color_code = QtCore.Qt.red
163            needs_background = "light"
164        elif color == "blue":
165            color_code = QtCore.Qt.blue
166            needs_background = "light"
167        elif color == "black":
168            color_code = QtCore.Qt.black
169            needs_background = "light"
170            self.text_item.setHtml("<div style='background:rgba(255, 255, 255, 255);'>" + str(self.text_item.toPlainText()).replace("\n","<br>") + "</div>")
171            self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(255, 255, 255, 255), xOffset=0, yOffset=0)
172            self.line_item.setGraphicsEffect(self.shadow)
173        elif color == "yellow":
174            needs_background = "dark"
175            color_code = QtCore.Qt.yellow
176        elif color == "green":
177            needs_background = "dark"
178            color_code = QtCore.Qt.green
179
180        if needs_background == "light":
181            self.text_item.setHtml("<div style='background:rgba(255, 255, 255, 123);'>" + str(self.text_item.toPlainText()).replace("\n","<br>") + "</div>")
182            self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(255, 255, 255, 255), xOffset=0, yOffset=0)
183        elif needs_background == "dark":
184            self.text_item.setHtml("<div style='background:rgba(0, 0, 0, 31);'>" + str(self.text_item.toPlainText()).replace("\n","<br>") + "</div>")
185            self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(0, 0, 0, 255), xOffset=0, yOffset=0)
186        
187        self.line_item.setGraphicsEffect(self.shadow)
188
189        
190        pen_ellipse.setColor(color_code)
191        pen_line.setColor(color_code)
192
193        self.ellipse_item.setPen(pen_ellipse)
194        self.line_item.setPen(pen_line)
195        self.text_item.setDefaultTextColor(color_code)

Create an editable and movable comment for QGraphicsScene.

Features:

Editable field for plain text. Draggable item with visible datum centered at actual location. Multiple color schemes.

Arguments:
  • initial_scene_pos (QPointF): The starting position of the comment datum on the scene.
  • color (str): The color scheme based on the presets of text color (white, red, blue, black, yellow, green).
  • comment_text (str): Text of the comment.
  • set_cursor_on_creation (bool): True to set cursor on comment text field on instantiation; False to ignore.
def set_cursor(self):
117    def set_cursor(self):
118        """Set cursor on the comment text field."""
119        self.text_item.setFocus(QtCore.Qt.MouseFocusReason)
120        self.text_item.setSelected(True);
121        cursor = self.text_item.textCursor()
122        cursor.select(QtGui.QTextCursor.Document)
123        self.text_item.setTextCursor(cursor)

Set cursor on the comment text field.

def get_scene_pos(self):
125    def get_scene_pos(self):
126        """QPointF: Get datum position of the comment."""
127        scene_pos = self.line_item_bounding_box.pos()
128        return scene_pos

QPointF: Get datum position of the comment.

def get_comment_text_qstring(self):
130    def get_comment_text_qstring(self):
131        """QString: Get comment text."""
132        text_qstring = self.text_item.toPlainText()
133        return text_qstring

QString: Get comment text.

def get_comment_text_str(self):
135    def get_comment_text_str(self):
136        """str: Get comment text."""
137        text_qstring = self.get_comment_text_qstring()
138        text_str = str(text_qstring)
139        return text_str

str: Get comment text.

def get_color(self):
141    def get_color(self):
142        """str: Get descriptor of color."""
143        color = self.color
144        return color

str: Get descriptor of color.

def set_color(self, color='white'):
146    def set_color(self, color="white"):
147        """Set color based on the presets of text color (white, red, blue, black, yellow, green).
148
149        Applies highlight behind the text to make it more visible over images.
150
151        Args:
152            color (str): The color scheme based on the presets of text color (white, red, blue, black, yellow, green).
153        """
154        pen_ellipse = self.ellipse_item.pen()
155        pen_line = self.line_item.pen()
156
157        self.color = color
158        needs_background = "dark"
159        color_code = QtCore.Qt.white
160
161        if color == "red":
162            color_code = QtCore.Qt.red
163            needs_background = "light"
164        elif color == "blue":
165            color_code = QtCore.Qt.blue
166            needs_background = "light"
167        elif color == "black":
168            color_code = QtCore.Qt.black
169            needs_background = "light"
170            self.text_item.setHtml("<div style='background:rgba(255, 255, 255, 255);'>" + str(self.text_item.toPlainText()).replace("\n","<br>") + "</div>")
171            self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(255, 255, 255, 255), xOffset=0, yOffset=0)
172            self.line_item.setGraphicsEffect(self.shadow)
173        elif color == "yellow":
174            needs_background = "dark"
175            color_code = QtCore.Qt.yellow
176        elif color == "green":
177            needs_background = "dark"
178            color_code = QtCore.Qt.green
179
180        if needs_background == "light":
181            self.text_item.setHtml("<div style='background:rgba(255, 255, 255, 123);'>" + str(self.text_item.toPlainText()).replace("\n","<br>") + "</div>")
182            self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(255, 255, 255, 255), xOffset=0, yOffset=0)
183        elif needs_background == "dark":
184            self.text_item.setHtml("<div style='background:rgba(0, 0, 0, 31);'>" + str(self.text_item.toPlainText()).replace("\n","<br>") + "</div>")
185            self.shadow = QtWidgets.QGraphicsDropShadowEffect(blurRadius=8, color=QtGui.QColor(0, 0, 0, 255), xOffset=0, yOffset=0)
186        
187        self.line_item.setGraphicsEffect(self.shadow)
188
189        
190        pen_ellipse.setColor(color_code)
191        pen_line.setColor(color_code)
192
193        self.ellipse_item.setPen(pen_ellipse)
194        self.line_item.setPen(pen_line)
195        self.text_item.setDefaultTextColor(color_code)

Set color based on the presets of text color (white, red, blue, black, yellow, green).

Applies highlight behind the text to make it more visible over images.

Arguments:
  • color (str): The color scheme based on the presets of text color (white, red, blue, black, yellow, green).